iphone/ipad: How exactly use NSAttributedString?

2019-01-01 01:56发布

问题:

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;

回答1:

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.



回答2:

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;


回答3:

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



回答4:

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.



回答5:

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;


回答6:

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];



回答7:

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;


回答8:

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


回答9:

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