iphone / ipad: Comment utiliser exactement NSAttributedString?

102

Oui, beaucoup de gens parlent de Rich Text sur iPhone / iPad et beaucoup connaissent NSAttributedString .

Mais comment utiliser NSAttributedString ? J'ai cherché pendant beaucoup de temps, aucun indice d'extrait pour cela.

Je sais comment mettre en place un NSAttributedString , alors que dois-je faire pour afficher un texte sur iPhone / iPad avec du texte enrichi?

La documentation officielle indique qu'il devrait être utilisé avec CoreText.Framework , qu'est-ce que cela signifie?

Existe-t-il un moyen simple comme celui-ci?

NSAttributedString *str;
.....
UILabel *label;
label.attributedString = str;
Jack
la source
La réponse ci-dessus est cependant correcte. Code comme ça et assurez-vous d'ajouter le framework CoreText à vos frameworks liés.
mxcl
Merci, j'ai laissé la bonne réponse à Wes
Jack
Three20 ressemble à une bibliothèque assez impressionnante: github.com/facebook/three20
David H
87
Three20 est de la merde.
bandejapaisa
4
C'est ennuyeux, mais je ne pense pas que ce soit la pire des choses. Depuis 6 mois, je gère un projet qui utilise Three20 ... certaines des choses qu'ils font avec la mémoire me déroutent. Le code est vraiment fragile car il ne gère pas la mémoire de manière orthodoxe. Il est de loin préférable de faire ce qu'ils fournissent vous-même. Il est peu probable que vous ayez besoin de tout ce qu'ils fournissent. Faites-le vous-même ... vous en apprendrez plus, c'est plus amusant, vous le ferez probablement mieux!
bandejapaisa

Réponses:

79

Vous devriez jeter un oeil à OHAttributedLabel d'AliSoftware . Il s'agit d'une sous-classe de UILabel qui dessine un NSAttributedString et fournit également des méthodes pratiques pour définir les attributs d'un NSAttributedString à partir des classes UIKit.

À partir de l'exemple fourni dans le 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.

Remarque: dans iOS 6+, vous pouvez rendre les chaînes attribuées à l'aide de la propriété AttributeText d'UILabel.

Nous s
la source
Il n'existe pas de UIAttributedLabel. Je pense que vous faites référence à OHAttributedLabel.
Erik B
5
Il a été renommé OHAttributedLabel lors d'un commit en novembre 2010 . J'ai mis à jour ma réponse.
Wes le
1
Merci Wes! Vous et Olivier Halligon qui avez écrit le code! Je vous remercie!
DenNukem le
1
Merci @Wes d'avoir mentionné ma classe, et merci @DenNukem pour les crédits ... Je ne savais pas que c'était si célèbre;) Quoi qu'il en soit, j'ai fait beaucoup de mises à jour et de corrections sur cette classe depuis le message original, alors ne le faites pas ' t oublier de retirer le repo github!
AliSoftware
J'obtiens une erreur sur chaque ligne de votre code. Selon la documentation, aucune des méthodes que vous avez fournies n'existe dans la classe actuelle, je suis confus: developer.apple.com/library/mac/#documentation/Cocoa/Reference/…
aryaxt
155

À partir d'iOS 6.0, vous pouvez le faire comme ça:

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;
RomanN
la source
60
La première règle du programme de développement iOS est de ne pas parler du programme de développement iOS.
Jeremy Moyers
5
La deuxième règle du programme de développement iOS est ... voir la première règle.
futureelite7
32
Dire que quelqu'un a violé la NDA, c'est confirmer que le matériel présenté est bien dans iOS6, et est donc en soi une violation de la NDA. Vous devriez écrire quelque chose comme "Il n'est pas possible de commenter ce qui est dans [version à venir] sans casser NDA".
hatfinch
Aussi, si vous vous retrouvez à écrire beaucoup de chaînes attribuées, consultez ce message / cette catégorie. Rend la création un peu plus facile. raizlabs.com/dev/2014/03/nsattributedstring-creation-helpers
Alex Rouse
15

Vous devriez essayer TTTAttributedLabel . Il s'agit d'un remplacement de UILabel qui fonctionne avec NSAttributedString et est suffisamment performant pour UITableViewCells.

mattt
la source
Cette classe se trouve dans la bibliothèque Three20 mentionnée ci-dessous.
David H du
10
Non, ce n'est pas de trois20 (notez les 3 Ts)
vikingosegundo
6

Existe-t-il des moyens simples comme

NSAttributedString * str;

Étiquette UILabel *;

label.attributedString = str;

Presque. Utilisez simplement un CATextLayer. Il a unstring propriété que vous pouvez définir sur NSAttributedString.

EDIT (novembre 2012): Bien sûr, tout cela a changé dans iOS 6. Dans iOS 6, vous pouvez faire exactement ce que l'OP a demandé - attribuer une chaîne attribuée directement à une étiquette attributedText.

mat
la source
1
Pourriez-vous être plus précis, par exemple fournir un exemple d'utilisation?
William Niu
1
Oui, ça s'appelle mon livre, Programming iOS 5. Voici l'exemple de code du livre: github.com/mattneub/Programming-iOS-Book-Examples/blob/master/…
matt
6

Réponse pour l'alignement de texte attribué par UILabel sur iOS 6: utilisez NSMutableAttributedString et ajoutez NSMutableParagraphStyle à l'attribut. Quelque chose comme ça:

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;
elou
la source
6

J'ai pensé qu'il serait utile de donner un exemple d'analyse d'une chaîne HTML (simplifiée), pour créer un NSAttributedString.

Ce n'est pas complet - il ne gère que les balises <b> et <i>, pour commencer, et ne se soucie pas de la gestion des erreurs - mais c'est aussi, espérons-le, un exemple utile de la façon de démarrer avec 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


Pour l'utiliser, faites quelque chose comme ceci:


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

Pete
la source
5

À partir d'iOS 6.0, vous pouvez le faire comme ça: un autre exemple de code.

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;
Ayaz
la source
2

Pour Swift, utilisez ceci,

Cela rendra les textes Titl gras,

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

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

    label.attributedText = title
Mohammad Zaid Pathan
la source
2

Je sais qu'il est un peu tard, mais ce sera utile aux autres,

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

[self.label setAttributedText:newString];

Ajoutez l'attribut souhaité au dictionnaire et transmettez-le en tant que paramètre d'attributs

satheesh
la source