UILabelでのテキスト表示をリッチにする

UILabelはiOSアプリ開発において使用頻度の高いUIコンポーネントですが、カユいところに手が届かなかったりします。例えばテキストの一部だけ強調表示したい、色を変えたい、フォントを変えたいといったHTMLのような使い方ができません。

iOS6以上であれば、`attributedText` というNSAttributedStringオブジェクトをセットできるプロパティを標準で持っているので、そのままでテキストの装飾が可能なのですが、残念ながらiOS5以下では使えません。

OHAttributedLabelとTTTAttributedLabelは、そんなUILabelの機能を拡張するOSSです。


##OHAttributedLabel

###特長

NSAttributedString をラップして UILabel に持たせたもので、テキストの一部だけフォントや色を変えたり、リンクの付与といった指定が簡単にできるようになります。

![OHAttributedLabel の使用例](http://f.cl.ly/items/3k0D0N3O1Q172D1K3z0d/OHSample_r1_c1.png)

また、 iOS6のテキスト装飾の手順と同じ（NSMutableAttributedString オブジェクトを作成して `attributedText` プロパティにセットする）で、シンプルでわかりやすいAPIも特長です。




###使用準備

1. ソースコードをダウンロード
https://github.com/AliSoftware/OHAttributedLabel
2. クラスファイル一式をプロジェクトに追加  
OHAttributedLabelフォルダ配下にあるクラスファイルをすべてプロジェクトに追加します。必要最小限のファイルのみ追加したい場合は
CoreTextUtils, NSTextCheckingResult+ExtendedURL, OHParagraphStyle, NSAttributedString+Attributes, OHAttributedLabelの5つを追加します。
3. CoreText.framework をプロジェクトに追加
4. ヘッダをインポート

````
#import "OHAttributedLabel.h"
````


##基本的な使用方法
指定範囲の文字色を変更する方法を例にとり、OHAttributedLabelの基本的な使い方の流れを説明します。

**1. NSMutableAttributedStringオブジェクトを生成**

引数には表示する文字列を渡します。

````
NSString *txt = @"表示する文字列";
NSMutableAttributedString *attrStr = [NSMutableAttributedString attributedStringWithString:txt];
````

**2. 文字色と範囲を指定**

`setTextColor:range:` メソッドで、変更する文字色と、変更する範囲を指定します。

````
NSRange range = [txt rangeOfString:@"文字"];
UIColor *color = [UIColor colorWithRed:0.f green:0.f blue:0.f alpha:1.f];
[attrStr setTextColor:color range:range];
````


**3. `attributedText`プロパティにセット**

OHAttributedLabel オブジェクトの attributedText プロパティに NSMutableAttributedString オブジェクトをセットして適用完了です。

````
self.ohLabel.attributedText = attrStr;
````

ちなみに、`setTextColor:range:` の代わりに range 引数のない `setTextColor:` メソッドを用いると、文字列全体に適用されます。

````
[attrStr setFont:[UIFont fontWithName:@"Helvetica" size:16]];
[attrStr setTextColor:[UIColor grayColor]];
````

###その他の使用方法

太字指定は `setTextBold:range:` メソッドで YES をセットするか、

````
[attrStr setTextBold:YES range:range];
````

ボールドフォントの UIFont オブジェクトを `setFont:range:` メソッドに渡します。

````
UIFont *boldFont = [UIFont boldSystemFontOfSize:18];
[attrStr setFont:boldFont range:strongRange];
````


リンクを貼る場合は、`setLink:range:` メソッドにURLと範囲を指定します。

````
NSRange linkRange = [txt rangeOfString:linkStr];
NSURL *linkUrl = [NSURL URLWithString:@"http://www.facebook.com/iOSDevTips"];
[attrStr setLink:linkUrl range:linkRange];
````

OHAttributedLabel のソースコードに付属しているサンプルプロジェクトには、デリゲートメソッドを実装してアラートを出したり、タップ済みのリンクの文字色を変えたりといったサンプルも入っています。


centerVertically プロパティに YES をセットすると中央揃え、NO で上寄せになります。

````
self.ohLabel.centerVertically = YES;
````


UILabel の textAlignment に指定できる値として、UITextAlignmentJustify が追加されています。これは

````
#define UITextAlignmentJustify ((UITextAlignment)kCTJustifiedTextAlignment)
````

このように CoreText で定義されているアライメントタイプである `kCTJustifiedTextAlignment` を UITextAlignment 型にキャストしたもので、これを指定すると**パラグラフの末尾が自然に揃えられます**。

````
self.ohLabel.textAlignment = UITextAlignmentJustify;
````


##TTTAttributedLabel

###特長

OHAttributedLabel と同じく、NSAttributedString の機能を UILabel に持たせたものです。APIの手軽さでは OHAttributedLabel に軍配が上がりますが、機能の豊富さではこちらが勝ります。

![TTTAttributedLabelの使用例](http://f.cl.ly/items/292q3c0i0z2v1r3X142T/TTTSample_r1_c1.png)

###使用準備

1. ソースコードをダウンロード  
https://github.com/mattt/TTTAttributedLabel
2. CoreText.framework をプロジェクトに追加
3. TTTAttributedLabel.h をインポート

````
#import "TTTAttributedLabel.h"
````


###使い方
OHAttributedLabel と使用方法の比較ができるよう、テキストの一部を赤字・太字にする方法、リンクを貼る方法を紹介します。


文字色、太字等の属性の指定は、`setText:afterInheritingLabelAttributesAndConfiguringWithBlock:` メソッドのブロック内で行います。

````
[self.tttLabel setText:txt afterInheritingLabelAttributesAndConfiguringWithBlock:
 ^NSMutableAttributedString *(NSMutableAttributedString *attrStr) {
     
     // ベースの設定
     [attrStr setFont:baseFont];
     [attrStr setTextColor:[UIColor grayColor]];

     // 文字色
     [attrStr setTextColor:strongColor range:strongRange];

     // Bold
     [attrStr setFont:boldFont range:strongRange];

     return attrStr;
 }];
````

###リンク

リンクの指定は `addLinkToURL:withRange:` メソッドをコールします。

````
[self.tttLabel addLinkToURL:linkUrl withRange:linkRange];
````

また、`TTTAttributedLabel`では、リンクをタップされたときの処理用の delegate メソッドを実装する必要があります。

そのため、プロトコルへの準拠を宣言しておき、

````
<TTTAttributedLabelDelegate>
````

TTTAttributedLabelの`delegate`プロパティに移譲先をセットします。

````
self.tttLabel.delegate = self;
````

`attributedLabel:didSelectLinkWithURL:` メソッドを実装します。

````
- (void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithURL:(NSURL *)url {
    
    [[UIApplication sharedApplication] openURL:self.linkUrl];
}
````






OHAttributedLabel はここはラップしてくれているのでひと手間増えることになりますが、`openURL:` ですぐに Safari や iTunes に飛ばすのではなく、一旦確認を挟みたい場合には便利です。（ただし、OHAttributedLabel もデリゲートメソッドの `attributedLabel:shouldFollowLink:` を実装すれば同等のことができます。）


##サンプルコード

OHAttributedLabel と TTTAttributedLabel ともにサンプルプロジェクトがそれぞれのリポジトリに付属していますが、両者のAPIの違いを比較しやすいよう、両OSSを使用したサンプルアプリをGithubにアップしてあります。

[LabelDemo](https://github.com/shu223/LabelDemo)

![サンプル](http://f.cl.ly/items/3Y2n0v2h1j2w251W1c2g/RichLabel_r1_c1.png)


##参考

- [UILabelでのテキスト表示をリッチにする機能拡張サブクラス3種](http://gihyo.jp/dev/serial/01/ios_oss/0004?ard=1363646129)
- [iOSオープンソースライブラリ徹底活用](http://www.amazon.co.jp/exec/obidos/ASIN/4798036277/22301-22/ref=nosim/)