属性付きテキストによるテキストの装飾(前編)
UIKit徹底解説 iOSユーザーインターフェイスの開発
iPhone/iPadアプリのUI開発テクニックを完全網羅!この記事は、書籍『UIKit徹底解説 iOSユーザーインターフェイスの開発』の内容を、Think IT向けに特別公開しているものです。
前回まではフォントのカスタマイズ方法を解説しました。フォントをカスタマイズすることで、テキストコンテンツのアピアランスは大きく変わります。しかし、本節で解説する属性付きテキストを利用すれば、フォントよりも大きな枠組みでテキストのアピアランスを調整できます。
テキストの装飾
属性付きテキスト(NSAttributedString)では、テキスト(NSString)に対して、色やアンダーラインなどの属性を辞書形式(NSDictionary)で指定します。属性は範囲と共に指定するため、テキスト内で複数の属性を混在させることが可能です。
テキストを表示するビューであるUILabelやUITextField、UITextViewはもちろん、一部のUIコントロール(UIButton、UIRefreshControl、UISegmentedControl、UIPickerView)やバー(UINavigationBar、UISearchBar)でも、属性付きテキストの使用が可能です。
例えば、文字色と背景色を指定するには、下記コードで属性付きテキストを生成します。
NSAttributedString *coloredText = [[NSAttributedString alloc] initWithString:@"色つきのテキスト" attributes:@{NSForegroundColorAttributeName: [UIColor redColor], NSBackgroundColorAttributeName: [UIColor lightGrayColor]}];
生成された属性付きテキストは、UILabelなどのattributedTextプロパティにセットして使用します。また、UITextViewでは、attributedTextプロパティの他にも、Text Kitを構成するtextStorageプロパティも利用できます(UITextStorageはNSMutableAttributedStringのサブクラス)。なお、NSTextStorageの詳細に関しては、「Text Kitによるテキストレイアウト」(連載後半)で解説します。
UIButton等のUIコントロールオブジェクトにも、属性付きテキストを指定することができます。例えば、UIButtonのタイトルは、setAttributedTitle:forState:メソッドにより指定します。
一方、バーやUISegmentedControlでは、テキストとは別に属性のみを指定します。例えば、UINavigationBarでタイトルに属性付き文字を適用するには、titleTextAttributesプロパティに属性だけをセットします。
属性の種類
テキスト装飾に使用可能な属性を、2回にわたり説明します。
詳細は「NSAttributedString UIKit Additionsリファレンスガイド」を参照してください。なお、特に指定がない限りiOS 6以降で使用可能です。
NSFontAttributeName
フォントを示すUIFontオブジェクトです。
NSParagraphStyleAttributeName
テキスト揃えなど、パラグラフ情報を示すNSParagraphStyleオブジェクトです。
例えば、テキストをセンタリングして表示するには、下記のパラグラフスタイルを設定します。
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle defaultParagraphStyle].mutableCopy; paragraphStyle.alignment = NSTextAlignmentCenter; NSAttributedString *centeringParagraph = [[NSAttributedString alloc] initWithString:@"1行目\n2行目\n3行目\n\n" attributes:@{NSParagraphStyleAttributeName: paragraphStyle}];
NSForegroundColorAttributeName
文字色を示すUIColorオブジェクトです。
NSBackgroundColorAttributeName
文字の背景色を示すUIColorオブジェクトです。
NSLigatureAttributeName
リガチャの有無を示すNSNumberオブジェクトです。
0はリガチャなし、1はリガチャありを意味します。
UIFont *font = [UIFont fontWithName:@"HoeflerText-Regular" size:26.0]; // リガチャなしテキスト NSAttributedString *noLigatureText = [[NSAttributedString alloc] initWithString:@"Affine Transform" attributes:@{NSLigatureAttributeName: @0, NSFontAttributeName: font}]; // リガチャありテキスト NSAttributedString *ligatureText = [[NSAttributedString alloc] initWithString:@"Affine Transform" attributes:@{NSLigatureAttributeName: @1, NSFontAttributeName: font}];
ソースコード25で生成したnoLigatureTextとligatureTextを表示した結果が下図です(図6)。「Affine」の「ffi」に注目すると、リガチャありの場合は「ffi」が繋がって表示されていることが分かります。
NSKernAttributeName
カーニングの設定値を示すNSNumber(float)オブジェクトです。
デフォルト値は0で、カーニング無効を示します。
UIFont *font = [UIFont fontWithName:@"HiraKakuProN-W6" size:30.0]; // カーニングなしのテキスト NSAttributedString *noKernText = [[NSAttributedString alloc] initWithString:@"アフィン変換" attributes:@{NSKernAttributeName: @0, NSFontAttributeName: font}]; // "ィ"の両脇の間隔のみ詰める NSMutableAttributedString *kernText = noKernText.mutableCopy; [kernText addAttribute:NSKernAttributeName value:@(-3.0f) range:NSMakeRange(1, 2)];
上記の例では、「アフィン変換」で「ィ」の両脇のスペースを詰めています。
テキストの一部のみにカーニング属性を適用するために、NSMutableAttributedStringのaddAttribute:value:range:メソッドを利用しています。上記で生成したテキストを表示した結果が下図です(図7)。