iphone / ipad: Cách sử dụng NSAttributedString chính xác như thế nào?


102

Có, nhiều người đang nói về Rich Text trong iPhone / iPad và nhiều người biết về nó NSAttributedString.

Nhưng sử dụng như thế nào NSAttributedString? Tôi đã tìm kiếm trong nhiều thời gian, không có manh mối trích xuất cho điều này.

Tôi biết cách thiết lập a NSAttributedString, sau đó tôi nên làm gì để hiển thị văn bản trên iPhone / iPad với văn bản đa dạng thức?

Các tài liệu chính thức nói rằng nó nên được sử dụng với CoreText.Framework, điều đó có nghĩa là gì?

Có cách nào đơn giản như thế này không?

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

Câu trả lời trên là đúng mặc dù. Mã như vậy và đảm bảo bạn thêm khung CoreText vào các khung được liên kết của mình.
mxcl

Cảm ơn, tôi rời khỏi câu trả lời đúng để Wes
Jack

Three20 ooks giống như một thư viện ấn tượng khá: github.com/facebook/three20
David H

87
Three20 là tào lao.
bandejapaisa

4
Thật là khó chịu, nhưng tôi không nghĩ đó là điều tồi tệ hơn. Trong 6 tháng qua, tôi đã duy trì một dự án sử dụng Three20 ... một số điều họ làm với bộ nhớ khiến tôi khó hiểu. Mã thực sự mỏng manh vì nó không xử lý bộ nhớ theo cách chính thống. Tốt hơn hết là tự mình làm những gì họ cung cấp. Không chắc bạn sẽ cần mọi thứ họ cung cấp. Hãy tự mình làm ... bạn sẽ học được nhiều hơn, sẽ vui hơn, có thể bạn sẽ làm tốt hơn!
bandejapaisa

Câu trả lời:


79

Bạn nên xem qua Nhãn OHAttributedLabel của AliSoftware . Nó là một lớp con của UILabel vẽ một NSAttributedString và cũng cung cấp các phương thức thuận tiện để thiết lập các thuộc tính của một NSAttributedString từ các lớp UIKit.

Từ mẫu được cung cấp trong 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.

Lưu ý: Trong iOS 6+, bạn có thể hiển thị các chuỗi được phân bổ bằng cách sử dụng thuộc tính Văn bản phân bổ của UILabel.


Không có cái gọi là UIAttributedLabel. Tôi nghĩ những gì bạn đang đề cập đến là OHAttributedLabel.
Erik B

5
Nó được đổi tên thành OHAttributedLabel trong một cam kết vào tháng 11 năm 2010 . Tôi đã cập nhật câu trả lời của mình.
Wes

1
Cảm ơn bạn Wes! Bạn và Olivier Halligon, người đã viết mã! Cảm ơn bạn!
DenNukem

1
Cảm ơn @Wes đã đề cập đến lớp học của tôi, và cảm ơn @DenNukem vì các khoản tín dụng ... Tôi không biết nó nổi tiếng đến vậy;) Dù sao, tôi đã thực hiện rất nhiều cập nhật và sửa chữa về lớp học này kể từ bài đăng gốc, vì vậy đừng ' đừng quên kéo repo github!
AliSoftware

Tôi gặp lỗi trên mỗi dòng mã của bạn. Theo tài liệu không có các phương thức bạn cung cấp tồn tại trong lớp thực tế, tôi nhầm lẫn: developer.apple.com/library/mac/#documentation/Cocoa/Reference/…
aryaxt

155

Bắt đầu từ iOS 6.0, bạn có thể làm như vậy:

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
Quy tắc đầu tiên của chương trình nhà phát triển iOS là không nói về chương trình nhà phát triển iOS.
Jeremy Moyers

5
Quy tắc thứ hai của chương trình nhà phát triển iOS là ... xem quy tắc đầu tiên.
futureelite 7

32
Tuyên bố rằng ai đó đã vi phạm NDA là xác nhận rằng tài liệu được trình bày thực sự là trong iOS6 và do đó, bản thân nó đã vi phạm NDA. Bạn nên viết đại loại như "Không thể bình luận về nội dung trong [phiên bản sắp tới] mà không vi phạm NDA".
hatfinch

Ngoài ra, nếu bạn thấy mình viết rất nhiều chuỗi phân bổ, hãy xem bài đăng / danh mục này. Làm cho việc tạo dễ dàng hơn một chút. raizlabs.com/dev/2014/03/nsattributedstring-creation-helpers
Alex Rouse

15

Bạn nên thử TTTAttributedLabel . Nó thay thế cho UILabel hoạt động với NSAttributedString và đủ hiệu suất cho UITableViewCells.


Lớp này được tìm thấy trong thư viện Three20 được đề cập bên dưới.
David H

10
Không, đây không phải là từ three20 (chú ý 3 Ts)
vikingosegundo

6

Có cách nào đơn giản như

NSAttributedString * str;

Nhãn UILabel *;

label.attributedString = str;

Hầu hết. Chỉ cần sử dụng CATextLayer. Nó có một thuộc stringtính mà bạn có thể đặt thành NSAttributedString.

CHỈNH SỬA (tháng 11 năm 2012): Tất nhiên tất cả điều này đã thay đổi trong iOS 6. Trong iOS 6, bạn có thể thực hiện chính xác những gì OP yêu cầu - chỉ định một chuỗi phân bổ trực tiếp cho một nhãn attributedText.


1
Bạn có thể cụ thể hơn, ví dụ: cung cấp cách sử dụng ví dụ?
William Niu

1
Có, nó được gọi là sách của tôi, Lập trình iOS 5. Đây là ví dụ mã từ cuốn sách: github.com/mattneub/Programming-iOS-Book-Examples/blob/master/…
matt

6

Câu trả lời cho căn chỉnh văn bản được gán cho UILabel trên iOS 6: Sử dụng NSMutableAttributedString và thêm NSMutableParagraphStyle vào thuộc tính. Một cái gì đó như thế này:

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

Tôi nghĩ sẽ rất hữu ích nếu đưa ra một ví dụ về phân tích cú pháp một chuỗi HTML (đơn giản hóa), để tạo một NSAttributedString.

Nó không hoàn chỉnh - nó chỉ xử lý các thẻ <b> và <i> cho người mới bắt đầu và không bận tâm đến bất kỳ xử lý lỗi nào - nhưng hy vọng đây cũng là một ví dụ hữu ích về cách bắt đầu với 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


Để sử dụng, hãy làm như sau:


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


5

Bắt đầu từ iOS 6.0, bạn có thể làm điều đó như sau: một mã mẫu khác.

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

Đối với Swift, hãy sử dụng cái này,

Nó sẽ làm cho văn bản Titl được in đậm,

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

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

    label.attributedText = title

2

Tôi biết là hơi muộn, nhưng nó sẽ hữu ích cho những người khác,

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

[self.label setAttributedText:newString];

Thêm thuộc tính mong muốn vào từ điển và chuyển nó dưới dạng tham số thuộc tính

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.