Iphone/ipad: 如何使用 NSAttributedString?

是的,很多人都在谈论 iPhone/iPad 中的 Rich Text,很多人都知道 NSAttributedString

但是如何使用 NSAttributedString呢? 我搜索了很长时间,没有提取到这方面的线索。

我知道如何设置一个 NSAttributedString,那么我应该怎么做才能在 iPhone/iPad 上显示富文本的文本?

官方文件说它应该和 CoreText.Framework一起使用,这是什么意思?

有没有这么简单的方法?

NSAttributedString *str;
.....
UILabel *label;
label.attributedString = str;
93424 次浏览

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.

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.

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

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;

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;

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 <b> and <i> 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];

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;

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

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