iphone / ipad: Bagaimana tepatnya menggunakan NSAttributedString?


102

Ya, banyak orang yang mengatakan tentang Rich Text di iPhone / iPad dan banyak yang mengetahuinya NSAttributedString.

Tapi bagaimana cara menggunakannya NSAttributedString? Saya mencari banyak waktu, tidak ada petunjuk untuk ini.

Saya tahu cara mengatur a NSAttributedString, lalu apa yang harus saya lakukan untuk menampilkan teks di iPhone / iPad dengan teks kaya?

Dokumen resmi mengatakan itu harus digunakan dengan CoreText.Framework, apa artinya?

Apakah ada cara sederhana seperti ini?

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

Jawaban di atas benar. Kode seperti itu dan pastikan Anda menambahkan kerangka kerja CoreText ke kerangka kerja Anda yang ditautkan.
mxcl

Terima kasih, saya meninggalkan jawaban yang benar untuk Wes
Jack

Three20 tampak seperti perpustakaan yang cukup mengesankan: github.com/facebook/three20
David H

87
Three20 adalah omong kosong.
bandejapaisa

4
Itu menjengkelkan, tapi menurutku itu bukan hal yang lebih buruk. Selama 6 bulan terakhir, saya telah memelihara proyek yang menggunakan Three20 ... beberapa hal yang mereka lakukan dengan memori membingungkan saya. Kode ini sangat rapuh karena tidak menangani memori dengan cara yang ortodoks. Jauh lebih baik melakukan apa yang mereka sediakan sendiri. Sepertinya Anda tidak akan membutuhkan semua yang mereka sediakan. Lakukan sendiri ... Anda akan belajar lebih banyak, itu lebih menyenangkan, Anda mungkin akan melakukannya dengan lebih baik!
bandejapaisa

Jawaban:


79

Anda harus melihat OHAttributedLabel AliSoftware . Ini adalah subkelas UILabel yang menarik NSAttributedString dan juga menyediakan metode praktis untuk menyetel atribut NSAttributedString dari kelas UIKit.

Dari contoh yang diberikan di 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.

Catatan: Di iOS 6+ Anda dapat merender string yang diatribusikan menggunakan properti AttributedText dari UILabel.


Tidak ada yang namanya UIAttributedLabel. Saya pikir yang Anda maksud adalah OHAttributedLabel.
Erik B

5
Itu diganti namanya menjadi OHAttributedLabel dalam komit pada November 2010 . Saya telah memperbarui jawaban saya.
Wes

1
Terima kasih Wes! Anda dan Olivier Halligon yang menulis kode! Terima kasih!
DenNukem

1
Terima kasih @Wes telah menyebutkan kelas saya, dan terima kasih @DenNukem atas kreditnya ... Saya tidak tahu itu sangat terkenal;) ​​Bagaimanapun, saya melakukan banyak pembaruan dan perbaikan pada kelas ini sejak posting asli, jadi jangan ' jangan lupa untuk menarik repo github!
AliSoftware

Saya mendapatkan kesalahan pada setiap baris kode Anda. Menurut dokumentasi
selain

155

Mulai dari iOS 6.0 Anda dapat melakukannya seperti itu:

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
Aturan pertama program pengembang iOS adalah tidak berbicara tentang program pengembang iOS.
Jeremy Moyers

5
Aturan kedua program pengembang iOS adalah ... lihat aturan pertama.
futureelite7

32
Menyatakan bahwa seseorang telah melanggar NDA berarti mengonfirmasi bahwa materi yang disajikan memang ada di iOS6, dan karena itu sendiri merupakan pelanggaran NDA. Anda harus menulis sesuatu seperti "Tidak mungkin mengomentari apa yang ada di [versi mendatang] tanpa melanggar NDA".
hatfinch

Juga jika Anda menemukan diri Anda menulis banyak string yang dikaitkan, periksa posting / kategori ini. Membuat kreasi sedikit lebih mudah. raizlabs.com/dev/2014/03/nsattributedstring-creation-helpers
Alex Rouse

15

Anda harus mencoba TTTAttributedLabel . Ini adalah pengganti drop-in untuk UILabel yang bekerja dengan NSAttributedString dan cukup berkinerja untuk UITableViewCells.


Kelas ini ditemukan di perpustakaan Three20 yang disebutkan di bawah ini.
David H

10
Tidak, ini bukan dari three20 (perhatikan 3 Ts)
vikingosegundo

6

Apakah ada cara sederhana seperti

NSAttributedString * str;

Label UILabel *;

label.attributedString = str;

Hampir. Cukup gunakan CATextLayer. Ini memiliki stringproperti yang dapat Anda setel ke NSAttributedString.

EDIT (November, 2012): Tentu saja semua ini telah berubah di iOS 6. Di iOS 6, Anda dapat melakukan persis apa yang diminta OP - menetapkan string yang dikaitkan langsung ke label attributedText.


1
Bisakah Anda lebih spesifik, misalnya memberikan contoh penggunaan?
William Niu

1
Ya, ini disebut buku saya, Pemrograman iOS 5. Berikut adalah contoh kode dari buku: github.com/mattneub/Programming-iOS-Book-Examples/blob/master/…
matt

6

Jawaban untuk perataan teks yang diatribusikan UILabel di iOS 6: Gunakan NSMutableAttributedString dan tambahkan NSMutableParagraphStyle ke atribut. Sesuatu seperti ini:

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

Saya pikir akan berguna untuk memberikan contoh parsing string HTML (disederhanakan), untuk membuat NSAttributedString.

Ini tidak lengkap - ini hanya menangani tag <b> dan <i>, sebagai permulaan, dan tidak mengganggu penanganan kesalahan apapun - tapi semoga juga menjadi contoh yang berguna tentang bagaimana memulai dengan 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


Untuk menggunakan, lakukan sesuatu seperti ini:


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


5

Mulai dari iOS 6.0 Anda dapat melakukannya seperti itu: kode contoh lain.

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

Untuk Swift gunakan ini,

Ini akan membuat teks Titl menjadi tebal,

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

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

    label.attributedText = title

2

Aku tahu ini agak terlambat, tapi ini akan berguna untuk yang lain,

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

[self.label setAttributedText:newString];

Tambahkan atribut yang diinginkan ke kamus dan teruskan sebagai parameter atribut

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.