iphone / ipad: як саме використовувати NSAttributedString?


102

Так, багато людей говорять про Rich Text в iPhone / iPad і багато хто про це знає NSAttributedString.

Але як користуватися NSAttributedString? Я шукав багато часу, жодних витяжок для цього не було.

Я знаю, як налаштувати a NSAttributedString, що мені робити, щоб відобразити текст на iPhone / iPad із сильним текстом?

Офіційні документи говорять, що його слід використовувати CoreText.Framework, що це означає?

Чи є такий простий спосіб, як це?

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

Наведена відповідь правильна, хоча. Код такого і забезпечте додавання основи CoreText до пов'язаних рам.
mxcl

Дякую, я залишив правильну відповідь Уесу
Джеку

Three20 виглядає як досить вражаюча бібліотека: github.com/facebook/three20
David H

87
Three20 - це лайно.
bandejapaisa

4
Це дратує, але я не думаю, що це гірше. Останні 6 місяців я підтримую проект, який використовує Three20 ... деякі речі, які вони роблять із пам’яттю, мене бентежать. Код дійсно крихкий, оскільки не обробляє пам'ять ортодоксально. Набагато краще робити те, що вони забезпечують самі. Навряд чи вам знадобиться все, що вони надають. Зробіть самі ... ви дізнаєтесь більше, це буде веселіше, напевно, зробите це краще!
bandejapaisa

Відповіді:


79

Спробуйте поглянути на OHAttributedLabel AliSoftware . Це підклас UILabel, який малює NSAttributedString, а також надає зручні методи встановлення атрибутів NSAttributedString з класів UIKit.

Зі зразка, наданого у репо-репортажі:

#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.
Ерік Б

5
У листопаді 2010 року він був перейменований на OHAttributedLabel . Я оновив свою відповідь.
Уес

1
Дякую Уес! Ви та Олів'є Галігон, які написали код! Дякую!
DenNukem

1
Дякую @Wes за те, що згадував мій клас, і дякую @DenNukem за кредити ... Я не знав, що він такий відомий;) У будь-якому разі, я зробив багато оновлень та виправлень для цього класу ще з початкової публікації, так що не ' не забудьте витягнути github repo!
AliSoftware

Я отримую помилку в кожному рядку вашого коду. Згідно з документацією, яка не є наданими вами методами у фактичному класі, я
плутаюсь

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
Перше правило програми dev iOS - це не говорити про програму iv dev.
Джеремі Моєрс

5
Друге правило програми розробки iOS - це ... див. Перше правило.
futureelite7

32
Стверджувати, що хтось порушив NDA - це підтвердити, що представлений матеріал дійсно знаходиться в iOS6, а тому сам по собі є порушенням NDA. Вам слід написати щось на кшталт "Неможливо коментувати те, що є у [майбутній версії], не порушуючи NDA".
hatfinch

Крім того, якщо ви описуєтесь, що ви пишете багато приписуваних рядків, ознайомтеся з цією публікацією / категорією. Полегшує створення. raizlabs.com/dev/2014/03/nsattributedstring-creation-helpers
Алекс

15

Спробуйте спробувати TTTAttributedLabel . Це замінна версія для UILabel, яка працює з NSAttributedString і є достатньо ефективною для UITableViewCells.


Цей клас знаходиться в бібліотеці Three20, згаданій нижче.
Девід Н

10
Ні, це не з трьох20 (зверніть увагу на 3 Ц)
vikingosegundo

6

Чи є прості способи, як

NSAttributedString * str;

UILabel * мітка;

label.attributedString = str;

Майже. Просто використовуйте CATextLayer. Він має stringвластивість, яку можна встановити на NSAttributedString.

EDIT (листопад 2012 р.): Зрозуміло, все це змінилося в iOS 6. У iOS 6 ви можете робити саме те, що просив ОП - присвоювати позначений рядок безпосередньо мітці attributedText.


1
Чи можете ви бути більш конкретними, наприклад, надати приклад використання?
Вільям Ніу

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

Додайте потрібний атрибут до словника та передайте його як параметр атрибутів

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.