(转)iOS 属性字符串

 

富文本的基本数据类型是NSAttributedString。**属性化字符串**(attributed string)是把属性设置到某些字符上的字符串。属性可以是任何键值对,但是为了实现富文本,则通常会包含样式信息,比如字体、颜色和缩进。

通常使用NSMutableAttributedString更好,这样我们就可以修改字符串各部分的属性。NSAttributedString则需要字符串的属性保持不变。

下面的例子将创建一个基本的矩形布局来在UITextView中显示一些富文本。相应的工程可以在名为RichText的示例代码中找到。首先,在Interface Builder中添加一个UITextView并且把模式选择为Attributed;然后,创建一个NSAttributedString并设置一些属性。在本例中,我们会创建一个字符串,然后对整个字符串设置字体属性。

ViewController.m(RichText)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
    const CGFloat fontSize = 16.0;

    // 创建基本字符串。
    // 注意如何定义一个多行的字符串
    NSString *string =
    @"Here is some simple text that includes bold and italics.n"
    @"n"
    @"We can even include some color.";

    // 创建可变属性化字符串
    NSMutableAttributedString *attrString =
    [[NSMutableAttributedString alloc] initWithString:string];

    NSUInteger length = [string length];

    // 设置基本字体
    UIFont *baseFont = [UIFont systemFontOfSize:fontSize];
    [attrString addAttribute:NSFontAttributeName value:baseFont
                        range:NSMakeRange(0, length)];

正如26.2.1节所讨论的那样,要设置粗体,需要设置不同的字体。对于系统字体来说这很简单,因为请求系统字体的粗体很容易:

1
2
3
4
    //用系统字体的粗体来设置粗体,搜索单词"bold"
    UIFont *boldFont = [UIFont boldSystemFontOfSize:fontSize];
    [attrString addAttribute:NSFontAttributeName value:boldFont
                        range:[string rangeOfString:@"bold"]];

但是如果你用的是非系统字体,而又需要粗体或斜体变体呢?不幸的是,UIKit没有很好的办法确定字体的变体,但是Core Text有。链接了CoreText.framework以后就可以用下面的函数了。该函数用UIFont的名字来找到正确的CTFont,然后用CTFontCreateCopyWithSymbolicTraits来添加所请求的变体(比如kCTFontTraitItalic),最后用得到的字体名称来创建正确的UIFont。但愿将来新版本的iOS能让这个过程变得容易一些。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    UIFont * GetVariationOfFontWithTrait(UIFont *baseFont,
                                         CTFontSymbolicTraits trait) {
      CGFloat fontSize = [baseFont pointSize];

      CFStringRef

      baseFontName = (__bridge CFStringRef)[baseFont fontName];
      CTFontRef baseCTFont = CTFontCreateWithName(baseFontName,
                                                  fontSize, NULL);
      CTFontRef ctFont =
      CTFontCreateCopyWithSymbolicTraits(baseCTFont, 0, NULL,
                                         trait, trait);

      NSString *variantFontName =
      CFBridgingRelease(CTFontCopyName(ctFont,
                                       kCTFontPostScriptNameKey));

      UIFont *variantFont = [UIFont fontWithName:variantFontName
                                            size:fontSize];

      CFRelease(ctFont);
      CFRelease(baseCTFont);

      return variantFont;
    }
    ...
    UIFont *italicFont = GetVariationOfFontWithTrait(baseFont,
                                                     kCTFontTraitItalic);
    [attrString addAttribute:NSFontAttributeName value:italicFont
                        range:[string rangeOfString:@"italics"]];

最后,添加合适的属性来加上颜色:

1
2
3
4
5
    // 设置颜色
    UIColor *color = [UIColor redColor];
    [attrString addAttribute:NSForegroundColorAttributeName
                        value:color
                        range:[string rangeOfString:@"color"]];

注意这里用了addAttribute:value:range:而不是setAttribute:value:range。这样可以把新属性和已有的属性合并,通常是我们所期望的结果。

设置好所有属性之后,可以给UITextView设置attributedText属性来显示这个字符串:

1
    self.textView.attributedText = attrString;

大部分具有text属性的控件现在也会有attributedText属性,这样转换已有的代码会容易得多。

有一点很重要,NSAttributedString不是NSString的子类。它包含了一个NSString对象。类似地,NSMutableAttributedString包含了一个NSMutableString对象。尽管属性化字符串也有常用的字符串方法(如length),但通常还得用stringmutalbeString来获取底层的字符串。

posted @ 2015-07-21 14:43  孤光一点莹  阅读(2114)  评论(0编辑  收藏  举报