iphone / ipad: ใช้ NSAttributedString อย่างไร?


102

มีหลายคนพูดเกี่ยวกับข้อความที่อุดมไปด้วย iPhone / iPad NSAttributedStringและหลายรู้เกี่ยวกับ

แต่จะใช้NSAttributedStringอย่างไร? ฉันค้นหาเป็นเวลานานไม่พบเบาะแสสำหรับสิ่งนี้

ฉันรู้วิธีตั้งค่าNSAttributedStringแล้วฉันควรทำอย่างไรเพื่อแสดงข้อความบน iPhone / iPad ด้วย Rich Text

เอกสารอย่างเป็นทางการบอกว่าควรใช้กับCoreText.Frameworkหมายความว่าอย่างไร?

มีวิธีง่ายๆแบบนี้ไหม?

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

คำตอบข้างต้นถูกต้องแม้ว่า โค้ดเช่นนั้นและให้แน่ใจว่าคุณได้เพิ่มกรอบงาน CoreText ไปยังกรอบงานที่เชื่อมโยงของคุณ
mxcl

ขอบคุณฉันทิ้งคำตอบที่ถูกต้องให้กับ Wes
Jack

Three20 ooks เหมือนห้องสมุดที่น่าประทับใจ: github.com/facebook/three20
David H

87
Three20 คืออึ
bandejapaisa

4
น่ารำคาญ แต่ฉันไม่คิดว่านั่นเป็นสิ่งที่แย่กว่านั้น ตลอด 6 เดือนที่ผ่านมาฉันดูแลโครงการที่ใช้ Three20 ... บางสิ่งที่พวกเขาทำกับความทรงจำทำให้ฉันยุ่งเหยิง รหัสมีความเปราะบางมากเนื่องจากไม่ได้จัดการกับหน่วยความจำในรูปแบบดั้งเดิม จะดีกว่ามากที่จะทำในสิ่งที่พวกเขาจัดหาให้ด้วยตัวคุณเอง ไม่น่าเป็นไปได้ที่คุณจะต้องการทุกอย่างที่มีให้ ทำด้วยตัวเอง ... คุณจะได้เรียนรู้มากขึ้นสนุกมากขึ้นคุณจะทำได้ดีกว่านี้!
bandejapaisa

คำตอบ:


79

คุณควรจะดูที่AliSoftware ของ OHAttributedLabel เป็นคลาสย่อยของ UILabel ที่ดึง NSAttributedString และยังมีวิธีอำนวยความสะดวกในการตั้งค่าแอตทริบิวต์ของ NSAttributedString จากคลาส UIKit

จากตัวอย่างที่ให้ไว้ใน 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.

หมายเหตุ:ใน iOS 6+ คุณสามารถแสดงสตริงที่มีการระบุแหล่งที่มาโดยใช้คุณสมบัติattributedTextของ UILabel


ไม่มีสิ่งที่เรียกว่า UIAttributedLabel ฉันคิดว่าสิ่งที่คุณอ้างถึงคือ OHAttributedLabel
Erik B

5
มันเป็นชื่อ OHAttributedLabel ในการกระทำในเดือนพฤศจิกายน 2010 ฉันได้อัปเดตคำตอบแล้ว
Wes

1
ขอบคุณเวส! คุณและ Olivier Halligon ผู้เขียนโค้ด! ขอบคุณ!
DenNukem

1
ขอบคุณ @ ที่กล่าวถึงชั้นเรียนของฉันและขอบคุณ @DenNukem สำหรับเครดิต ... ฉันไม่รู้ว่ามันโด่งดังมาก;) อย่างไรก็ตามฉันได้อัปเดตและแก้ไขในชั้นเรียนนี้มากมายตั้งแต่โพสต์ต้นฉบับดังนั้นอย่า ' อย่าลืมดึง github repo!
AliSoftware

ฉันได้รับข้อผิดพลาดในทุกบรรทัดของรหัสของคุณ ตามเอกสารที่ไม่ใช่วิธีการที่คุณให้ไว้มีอยู่ในคลาสจริงฉันสับสน: developer.apple.com/library/mac/#documentation/Cocoa/Reference/…
aryaxt

155

เริ่มจาก iOS 6.0 คุณสามารถทำได้ดังนี้:

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
กฎข้อแรกของโปรแกรม iOS dev คือไม่ต้องพูดถึงโปรแกรม iOS dev
Jeremy Moyers

5
กฎข้อที่สองของโปรแกรม iOS dev คือ ... ดูกฎข้อแรก
futureelite 7

32
ในการระบุว่ามีผู้ละเมิด NDA คือการยืนยันว่าเนื้อหาที่นำเสนอนั้นอยู่ใน iOS6 จริง ๆ ดังนั้นจึงเป็นการละเมิด NDA คุณควรเขียนข้อความเช่น "เป็นไปไม่ได้ที่จะแสดงความคิดเห็นเกี่ยวกับสิ่งที่อยู่ใน [เวอร์ชันที่กำลังจะมาถึง] โดยไม่ทำลาย NDA"
hatfinch

นอกจากนี้หากคุณพบว่าตัวเองกำลังเขียนสตริงที่มีแหล่งที่มาจำนวนมากให้ตรวจสอบโพสต์ / หมวดหมู่ ทำให้การสร้างง่ายขึ้นเล็กน้อย raizlabs.com/dev/2014/03/nsattributedstring-creation-helpers
Alex Rouse

15

คุณควรพยายามTTTAttributedLabel เป็นการแทนที่ UILabel แบบดรอปอินที่ทำงานร่วมกับ NSAttributedString และมีประสิทธิภาพเพียงพอสำหรับ UITableViewCells


คลาสนี้พบได้ในไลบรารี Three20 ที่กล่าวถึงด้านล่าง
David H

10
ไม่นี่ไม่ใช่จาก three20 (หมายเหตุ 3 Ts)
vikingosegundo

6

มีวิธีง่ายๆเช่น

NSAttributedString * str;

ฉลาก UILabel *;

label.attributedString = str;

เกือบ. เพียงใช้ CATextLayer มีstringคุณสมบัติที่คุณสามารถตั้งค่าเป็น NSAttributedString

แก้ไข (พฤศจิกายน 2012): แน่นอนทั้งหมดนี้มีการเปลี่ยนแปลงใน iOS 6 ใน iOS 6 คุณสามารถทำสิ่งที่ OP ถาม - attributedTextกำหนดสตริงประกอบโดยตรงกับฉลาก


1
คุณสามารถเจาะจงมากขึ้นได้ไหมเช่นให้ตัวอย่างการใช้งาน
William Niu

1
ใช่มันเรียกว่าหนังสือของฉันการเขียนโปรแกรม iOS 5 นี่คือตัวอย่างโค้ดจากหนังสือ: github.com/mattneub/Programming-iOS-Book-Examples/blob/master/…
แมตต์

6

คำตอบสำหรับการจัดตำแหน่งข้อความที่ประกอบ UILabel บน iOS 6: ใช้ NSMutableAttributedString และเพิ่ม NSMutableParagraphStyle ให้กับแอตทริบิวต์ สิ่งนี้:

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

ฉันคิดว่าการยกตัวอย่างการแยกวิเคราะห์สตริง HTML (แบบง่าย) จะเป็นประโยชน์เพื่อสร้าง NSAttributedString

ยังไม่สมบูรณ์ - จัดการเฉพาะแท็ก <b> และ <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


หากต้องการใช้ให้ทำสิ่งนี้:


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


5

เริ่มจาก iOS 6.0 คุณสามารถทำได้เช่นนั้น: โค้ดตัวอย่างอื่น

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

สำหรับSwift ให้ใช้สิ่งนี้

จะทำให้ข้อความTitl เป็นตัวหนา

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

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

    label.attributedText = title

2

ฉันรู้ว่ามันช้าไปหน่อย แต่มันจะมีประโยชน์กับคนอื่น ๆ

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

[self.label setAttributedText:newString];

เพิ่มแอตทริบิวต์ที่ต้องการในพจนานุกรมและส่งเป็นพารามิเตอร์แอตทริบิวต์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.