iphone / ipad: come utilizzare esattamente NSAttributedString?


102

Sì, molte persone parlano di Rich Text in iPhone / iPad e molti lo sanno NSAttributedString.

Ma come si usa NSAttributedString? Ho cercato molto tempo, nessun indizio per estrarre questo.

So come impostare un NSAttributedString, quindi cosa devo fare per visualizzare un testo su iPhone / iPad con testo RTF?

La documentazione ufficiale dice che dovrebbe essere usato con CoreText.Framework, cosa significa?

C'è un modo semplice come questo?

NSAttributedString *str;
.....
UILabel *label;
label.attributedString = str;

La risposta di cui sopra è corretta però. Codice come quello e assicurati di aggiungere il framework CoreText ai tuoi framework collegati.
mxcl

Grazie, ho lasciato la risposta corretta a Wes
Jack

Three20 ooks like a pretty impressionante library: github.com/facebook/three20
David H

87
Three20 è una schifezza.
bandejapaisa

4
È fastidioso, ma non credo sia la cosa peggiore. Negli ultimi 6 mesi, ho mantenuto un progetto che utilizza Three20 ... alcune delle cose che fanno con la memoria mi lasciano perplesso. Il codice è davvero fragile in quanto non gestisce la memoria in modo ortodosso. È molto meglio fare ciò che ti forniscono. È improbabile che tu abbia bisogno di tutto ciò che forniscono. Fai da te ... imparerai di più, è più divertente, probabilmente lo farai meglio!
bandejapaisa

Risposte:


79

Dovresti dare un'occhiata a OHAttributedLabel di AliSoftware . È una sottoclasse di UILabel che disegna una NSAttributedString e fornisce anche metodi convenienti per impostare gli attributi di una NSAttributedString dalle classi UIKit.

Dall'esempio fornito nel repo:

#import "NSAttributedString+Attributes.h"
#import "OHAttributedLabel.h"

/**(1)** Build the NSAttributedString *******/
NSMutableAttributedString* attrStr = [NSMutableAttributedString attributedStringWithString:@"Hello World!"];
// for those calls we don't specify a range so it affects the whole string
[attrStr setFont:[UIFont systemFontOfSize:12]];
[attrStr setTextColor:[UIColor grayColor]];
// now we only change the color of "Hello"
[attrStr setTextColor:[UIColor redColor] range:NSMakeRange(0,5)];


/**(2)** Affect the NSAttributedString to the OHAttributedLabel *******/
myAttributedLabel.attributedText = attrStr;
// Use the "Justified" alignment
myAttributedLabel.textAlignment = UITextAlignmentJustify;
// "Hello World!" will be displayed in the label, justified, "Hello" in red and " World!" in gray.

Nota: in iOS 6+ puoi eseguire il rendering di stringhe con attributi utilizzando la proprietà attributeText di UILabel.


Non esiste un'etichetta UIAttributedLabel. Penso che quello a cui ti riferisci sia OHAttributedLabel.
Erik B

5
È stato rinominato OHAttributedLabel in un commit nel novembre 2010 . Ho aggiornato la mia risposta.
Wes

1
Grazie Wes! Tu e Olivier Halligon che hai scritto il codice! Grazie!
DenNukem

1
Grazie @Wes per aver menzionato la mia classe e grazie @DenNukem per i riconoscimenti ... non sapevo che fosse così famoso;) Ad ogni modo, ho fatto molti aggiornamenti e correzioni su questa classe dal post originale, quindi non non dimenticare di tirare il repository github!
AliSoftware

Ottengo un errore su ogni singola riga del tuo codice. Secondo la documentazione, i metodi che hai fornito non esistono nella classe attuale, sono confuso: developer.apple.com/library/mac/#documentation/Cocoa/Reference/…
aryaxt

155

A partire da iOS 6.0 puoi farlo in questo modo:

NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:@"Hello. That is a test attributed string."];
[str addAttribute:NSBackgroundColorAttributeName value:[UIColor yellowColor] range:NSMakeRange(3,5)];
[str addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(10,7)];
[str addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"HelveticaNeue-Bold" size:20.0] range:NSMakeRange(20, 10)];
label.attributedText = str;

60
La prima regola del programma di sviluppo iOS è non parlare del programma di sviluppo iOS.
Jeremy Moyers

5
La seconda regola del programma di sviluppo iOS è ... vedi la prima regola.
futureelite7

32
Affermare che qualcuno ha violato la NDA significa confermare che il materiale presentato è effettivamente in iOS6, ed è quindi essa stessa una violazione della NDA. Dovresti scrivere qualcosa come "Non è possibile commentare cosa c'è nella [versione imminente] senza rompere l'NDA".
Hatchfinch

Inoltre, se ti ritrovi a scrivere molte stringhe attribuite, dai un'occhiata a questo articolo / categoria. Rende la creazione un po 'più semplice. raizlabs.com/dev/2014/03/nsattributedstring-creation-helpers
Alex Rouse

15

Dovresti provare TTTAttributedLabel . È un sostituto immediato per UILabel che funziona con NSAttributedString ed è abbastanza performante per UITableViewCells.


Questa classe si trova nella libreria Three20 menzionata di seguito.
David H

10
No, questo non è da tre20 (nota le 3 T)
vikingosegundo

6

Esistono modi semplici come

NSAttributedString * str;

Etichetta UILabel *;

label.attributedString = str;

Quasi. Usa semplicemente un CATextLayer. Ha una stringproprietà che puoi impostare su NSAttributedString.

EDIT (novembre 2012): Ovviamente tutto questo è cambiato in iOS 6. In iOS 6, puoi fare esattamente ciò che l'OP ha richiesto: assegnare una stringa attribuita direttamente a un'etichetta attributedText.


1
Potresti essere più specifico, ad esempio fornire un esempio di utilizzo?
William Niu

1
Sì, si chiama il mio libro, Programmazione iOS 5. Ecco il codice di esempio dal libro: github.com/mattneub/Programming-iOS-Book-Examples/blob/master/...
matt

6

Risposta per l'allineamento del testo attribuito a UILabel su iOS 6: usa NSMutableAttributedString e aggiungi NSMutableParagraphStyle all'attributo. Qualcosa come questo:

NSString *str = @"Hello World!";
NSRange strRange = NSMakeRange(0, str.length);
NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:str];

NSMutableParagraphStyle *paragrahStyle = [[NSMutableParagraphStyle alloc] init];
[paragrahStyle setAlignment:NSTextAlignmentCenter];
[attributedStr addAttribute:NSParagraphStyleAttributeName value:paragrahStyle range:strRange];

myUILabel.attributedText = attributedStr;

6

Ho pensato che sarebbe stato utile fornire un esempio di analisi di una stringa HTML (semplificata), per creare una stringa NSAttributedString.

Non è completo: gestisce solo i tag <b> e <i>, tanto per cominciare, e non si preoccupa della gestione degli errori - ma si spera che sia anche un utile esempio di come iniziare con NSXMLParserDelegate ...


@interface ExampleHTMLStringToAttributedString : NSObject<NSXMLParserDelegate>

+(NSAttributedString*) getAttributedStringForHTMLText:(NSString*)htmlText WithFontSize:(CGFloat)fontSize;

@end

@interface ExampleHTMLStringToAttributedString()
@property NSString *mpString;
@property NSMutableAttributedString *mpAttributedString;

@property CGFloat mfFontSize;
@property NSMutableString *appendThisString;
@property BOOL mbIsBold;
@property BOOL mbIsItalic;
@end

@implementation ExampleHTMLStringToAttributedString
@synthesize mpString;
@synthesize mfFontSize;
@synthesize mpAttributedString;
@synthesize appendThisString;
@synthesize mbIsBold;
@synthesize mbIsItalic;

+(NSAttributedString*) getAttributedStringForHTMLText:(NSString*)htmlText WithFontSize:(CGFloat)fontSize {

    ExampleHTMLStringToAttributedString *me = [[ExampleHTMLStringToAttributedString alloc] initWithString:htmlText];
    return [me getAttributedStringWithFontSize:fontSize];
}

- (id)initWithString:(NSString*)inString {
    self = [super init];
    if (self) {
        if ([inString hasPrefix:@""]) {
          mpString = inString;
        } else {
            mpString = [NSString stringWithFormat:@"%@", inString];
        }
        mpAttributedString = [NSMutableAttributedString new];
    }
    return self;
}

-(NSAttributedString*) getAttributedStringWithFontSize:(CGFloat)fontSize {

    mfFontSize = fontSize;

    // Parse the XML
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:[mpString dataUsingEncoding:NSUTF8StringEncoding]];
    parser.delegate = self;
    if (![parser parse]) {
        return nil;
    }

    return mpAttributedString;
}

-(void) appendTheAccumulatedText {
    UIFont *theFont = nil;

    if (mbIsBold && mbIsItalic) {
        // http://stackoverflow.com/questions/1384181/italic-bold-and-underlined-font-on-iphone
        theFont = [UIFont fontWithName:@"Helvetica-BoldOblique" size:mfFontSize];
    } else if (mbIsBold) {
       theFont = [UIFont boldSystemFontOfSize:mfFontSize];
    } else if (mbIsItalic) {
        theFont = [UIFont italicSystemFontOfSize:mfFontSize];
    } else {
        theFont = [UIFont systemFontOfSize:mfFontSize];
    }

    NSAttributedString *appendThisAttributedString =
    [[NSAttributedString alloc]
     initWithString:appendThisString
     attributes:@{NSFontAttributeName : theFont}];

    [mpAttributedString appendAttributedString:appendThisAttributedString];

    [appendThisString setString:@""];
}

#pragma NSXMLParserDelegate delegate

-(void)parserDidStartDocument:(NSXMLParser *)parser{
    appendThisString = [NSMutableString new];
    mbIsBold = NO;
    mbIsItalic = NO;
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    if ([elementName isEqualToString:@"body"]){
    } else if ([elementName isEqualToString:@"i"]) {
      [self appendTheAccumulatedText];
        mbIsItalic = YES;
    } else if ([elementName isEqualToString:@"b"]) {
      [self appendTheAccumulatedText];
        mbIsBold = YES;
    }
}

-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
    if ([elementName isEqualToString:@"body"]){
      [self appendTheAccumulatedText];
    } else if ([elementName isEqualToString:@"i"]) {
      [self appendTheAccumulatedText];
      mbIsItalic = NO;
    } else if ([elementName isEqualToString:@"b"]) {
        [self appendTheAccumulatedText];
        mbIsBold = NO;
    }
}

-(void)parserDidEndDocument:(NSXMLParser *)parser{
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    [appendThisString appendString:string];
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
}

@end


Per usarlo, fai qualcosa di simile:


  self.myTextView.attributedText = [ExampleHTMLStringToAttributedString getAttributedStringForHTMLText:@"this is <b>bold</b> text" WithFontSize:self.myTextView.pointSize];


5

A partire da iOS 6.0 puoi farlo in questo modo: un altro codice di esempio.

NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:@"This is my test code to test this label style is working or not on the text to show other user"];

[str addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0,31)];
[str addAttribute:NSBackgroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(61,10)];

[str addAttribute:NSFontAttributeName value: [UIFont fontWithName:@"Helvetica-Bold" size:13.0] range:NSMakeRange(32, 28)];
[str addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Helvetica-Bold" size:13.0] range:NSMakeRange(65, 20)];

_textLabel.attributedText = str;

2

Per Swift usa questo,

Si farà titl testi in grassetto,

var title = NSMutableAttributedString(string: "Title Text")

    title.addAttributes([NSFontAttributeName: UIFont(name: "AvenirNext-Bold", size: iCurrentFontSize)!], range: NSMakeRange(0, 4))

    label.attributedText = title

2

So che è un po 'tardi, ma sarà utile ad altri,

NSMutableAttributedString* attrStr = [[NSMutableAttributedString alloc] initWithString:@"string" attributes:@{NSForegroundColorAttributeName:[UIColor blackColor]}];

[self.label setAttributedText:newString];

Aggiungere l'attributo desiderato al dizionario e passarlo come parametro di attributi

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.