ChatGPT解决这个技术问题 Extra ChatGPT

iphone/ipad: How exactly use NSAttributedString?

Yes, many people are saying about Rich Text in iPhone/iPad and many knows about NSAttributedString.

But how to use NSAttributedString? I searched for much time, no extract clues for this.

I know how to set up a NSAttributedString, then what should I do to display a text on iPhone/iPad with rich text?

The official docs says it should be used with CoreText.Framework, what does that mean?

Is there any simple way like this?

NSAttributedString *str;
.....
UILabel *label;
label.attributedString = str;
The above answer is correct though. Code like that and ensure you add the CoreText framework to your linked frameworks.
Thanks, i left the correct answer to Wes
Three20 ooks like a pretty impressive library: github.com/facebook/three20
Three20 is crap.
Thats annoying, but I don't think that's the worse thing. For the past 6 months, I've been maintaining a project that uses Three20... some of the things they do with memory baffle me. The code is really fragile as it doesn't handle memory in an orthodox way. It's far better to do what they provide yourself. It's unlikely you're going to need everything they provide. Do it yourself... you'll learn more, it's more fun, you'll probably do it better!

R
RomanN

Starting from the iOS 6.0 you can do it like that:

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;

The first rule of iOS dev program is not to talk about the iOS dev program.
The second rule of iOS dev program is... see the first rule.
To state that someone has violated the NDA is to confirm that the material presented is indeed in iOS6, and is therefore itself a violation of the NDA. You should write something like "It's not possible to comment on what's in [upcoming version] without breaking NDA".
Also if you find yourself writing a lot of attributed strings check out this post/category. Makes creation a bit easier. raizlabs.com/dev/2014/03/nsattributedstring-creation-helpers
W
Wes

You should take a look at AliSoftware's OHAttributedLabel. It is a subclass of UILabel that draws an NSAttributedString and also provides convenience methods for setting the attributes of an NSAttributedString from UIKit classes.

From the sample provided in the 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.

Note: In iOS 6+ you can render attributed strings using the attributedText property of UILabel.


There is no such thing as a UIAttributedLabel. I think what you're referring to is OHAttributedLabel.
It was renamed OHAttributedLabel in a commit in November 2010. I've updated my answer.
Thank you Wes! You and Olivier Halligon who wrote the code! Thank you!
Thanks @Wes for mentioning my class, and thanks @DenNukem for the credits... I wasn't aware it was so famous ;) Anyway, I did a lot of updates and fixes on this class since the original post, so don't forget to pull the github repo!
I get an error on every single line of your code. According to the documentation non of the methods you provided exist in the actual class, I am confused : developer.apple.com/library/mac/#documentation/Cocoa/Reference/…
m
mattt

You should try TTTAttributedLabel. It's a drop-in replacement for UILabel that works with NSAttributedString and is performant enough for UITableViewCells.


This class is found in the Three20 library mentioned below.
No, this is not from three20 (note the 3 Ts)
m
matt

Is there any simple ways like NSAttributedString *str; UILabel *label; label.attributedString = str;

Almost. Just use a CATextLayer. It has a string property that you can set to an NSAttributedString.

EDIT (November, 2012): Of course all this has changed in iOS 6. In iOS 6, you can do exactly what the OP asked for - assign an attributed string directly to a label's attributedText.


Could you be more specific, e.g. provide an example usage?
Yes, it's called my book, Programming iOS 5. Here's the code example from the book: github.com/mattneub/Programming-iOS-Book-Examples/blob/master/…
e
elou

Answer for UILabel attributed text alignment on iOS 6: Use NSMutableAttributedString and add NSMutableParagraphStyle to the attribute. Something like this:

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;

P
Pete

I thought it would be useful to give an example of parsing a (simplified) HTML string, to create an NSAttributedString.

It isn't complete - it only handles and tags, for starters, and doesn't bother with any error handling - but is hopefully also a useful example of how to get started with 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

To use, do something like this:


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

A
Ayaz

Starting from the iOS 6.0 you can do it like that: another sample 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;

M
Mohammad Zaid Pathan

For Swift use this,

It will make Titl texts bold,

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

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

    label.attributedText = title

s
satheesh

I know it is little bit late, But it will be useful to other,

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

[self.label setAttributedText:newString];

Add the desired attribute to the dictionary and pass it as a attributes parameter