UILabelに「lineSpacing」というプロパティを追加して、見事にはまったので書き残しておきます。
いまさら感に溢れていますが、iOS 6.0からUILabelがNSAttributedStringに対応し、装飾付きのテキストを設定できるようになりました。例えば、
[[NSAttributedString alloc] initWithString:str attributes:attrs]
みたいに初期化すれば、装飾情報をNSDictionaryで指定することができます。 設定できる属性の一覧は、公式リファレンス「NSAttributedString UIKit Additions」に載っています。
今回の目的は、UILabelの行間を簡単に設定できるようにすることです。
行間は、先ほどのリファレンスによるとNSParagraphStyleのプロパティとして設定します。ただ、毎回NSParagraphStyleを生成して、属性の辞書を生成して、…と諸々設定するのは面倒ですよね。
UILabelを継承してlineSpacingプロパティを追加し、内側でうまいことやれば楽になるのでは?
設定用の「lineSpacing」プロパティを試しに追加してみました。
@interface MyLabel : UILabel
@property (nonatomic) CGFloat lineSpacing;
@end
…が、追加した瞬間、ラベルのテキストが描画されなくなってしまいました。lineSpacingプロパティの定義を外せば元に戻ります。
ふーむ、これは…
「UILabelのプライベートな定義と重複している」と直感が囁いている!!
直感が正しいかどうかを確認するため、UILabelのプライベートを覗いてみましょう。
class-dumpというコマンドラインのツールがありまして、指定したframeworkのクラスを走査し、プライベートな定義も含めすべてダンプしてくれます。すてきですね。
UILabelはUIKit一族なので、該当するframeworkは「UIKit.framework」です。ディレクトリの奥深くに眠っているので、探し出してそのパスをclass-dumpに渡します。他の方が通ってきた道をありがたく辿りながら、class-dumpを実行。
% ./class-dump -H -o UIKit /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/UIKit.framework
無事に出力できたようです。 さっそくUIKit/UILabel.hを見てみると…
あった!やっぱりあったよ! 隠さずに提供してくれてもいいのよ…。あるいは警告のひとつでも出していただけないでしょうか、Xcodeさん。
名前が衝突してしまうと、予期しない動作を引き起こす可能性があります。今回のようなケースでは、追加するプロパティを他の名前、例えばmyLineSpacingにして回避する必要がありそうです。