その後のその後

iOSエンジニア 堤 修一のブログ github.com/shu223

UILabel, UITextView, UITextFieldのテキストを NSAttributedString で装飾する

iOS6から、UILabel, UITextView, UITextFieldに、 attributedText というNSAttributedString型のプロパティが追加されました。NSAttributedStringは文字列の属性を管理するクラスで、これを使用するとフォントや文字色、背景色、カーニング等の属性をテキスト内の指定範囲に対して適用することができるようになります。


基本的な実装手順

基本的な手順は次の通りです。


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


initWithString: メソッドでオブジェクトを生成します。

NSString *str = @"NSAttributedString Sample";
NSMutableAttributedString *attrStr;
attrStr = [[NSMutableAttributedString alloc] initWithString:str];

引数には対象となる文字列を渡します。


2. 属性をセット


addAttribute:value:range: メソッドを用いて属性、値、適用範囲をセットします。

// フォント
[attrStr addAttribute:NSFontAttributeName
                value:[UIFont fontWithName:@"Futura-CondensedMedium" size:17.]
                range:NSMakeRange(0, [attrStr length])];

// 背景色
[attrStr addAttribute:NSBackgroundColorAttributeName
                value:[UIColor colorWithRed:1. green:1. blue:.0 alpha:1.]
                range:NSMakeRange(0, [attrStr length])];

// 打ち消し線
[attrStr addAttribute:NSStrikethroughStyleAttributeName
                value:[NSNumber numberWithInt:3]
                range:[str rangeOfString:@"Sample"]];


3. UILabelにセット


UILabelの attributedText プロパティに、作成したNSMutableAttributedStringオブジェクトをセットします。

[self.label setAttributedText:attrStr];


なお、サンプルではUILabelを用いていますが、UITextViewもUITextFieldもiOS6以上では同様の方法(attributedTextプロパティを使う)でテキストに装飾することができます。


属性と値について

上で載せたサンプルで addAttribute:value:range: メソッドに渡している属性は、それぞれ次のような効果があります。

  • NSFontAttributeName :フォントを指定する
  • NSBackgroundColorAttributeName :背景色を指定する
  • NSStrikethroughStyleAttributeName :打ち消し線を指定する

そして、属性毎に引数valueに指定できる値の型は違ってきます。たとえば、属性 NSFontAttributeName に対して値はUIFontオブジェクトを渡しますが、属性 NSBackgroundColorAttributeName に対しては値としてUIColorオブジェクトを渡します。

属性毎に指定できる値の詳細は、


NSAttributedString UIKit Additions Reference


で確認することができます。

影と文字色

文字色を指定する場合は NSForegroundColorAttributeName を使用します。値は NSBackgroundColorAttributeName と同様にUIColorオブジェクトを渡します。


また影をつける場合は NSShadowAttributeName を使用します。値にはNSShadowオブジェクトを渡します。

// NSShadowオブジェクト
NSShadow *shadow = [[NSShadow alloc] init];
[shadow setShadowColor:[UIColor colorWithRed:0. green:0. blue:0. alpha:1.]];
[shadow setShadowBlurRadius:4.0];
[shadow setShadowOffset:CGSizeMake(2, 2)];

// 影
[attrStr addAttribute:NSShadowAttributeName
                value:shadow
                range:NSMakeRange(0, [attrStr length])];

// 文字色
[attrStr addAttribute:NSForegroundColorAttributeName
                value:[UIColor colorWithRed:1. green:1. blue:0. alpha:1.]
                range:NSMakeRange(0, [attrStr length])];


中抜き文字、下線、カーニング

NSStrokeWidthAttributeName を使用すると、中抜き文字にすることができます。値には線幅を指定します。中抜き文字の枠線の色を指定する場合は、 NSStrokeColorAttributeName を使用します。


下線を引く場合は、 NSUnderlineStyleAttributeName を使用します。値には整数のNSNumberオブジェクトを指定します。(ここでは定数 NSUnderlineStyleSingle を使用しています。)


カーニングは NSKernAttributeName を使用します。値には浮動小数点数のNSNumberオブジェクトを指定します。

// 中抜き文字の線幅
[attrStr addAttribute:NSStrokeWidthAttributeName
                value:@5
                range:NSMakeRange(0, [attrStr length])];

// 中抜き文字の枠線の色、下線、カーニングを一度に指定
NSDictionary *attributes = @{NSStrokeColorAttributeName: [UIColor magentaColor],
                             NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle),
                             NSKernAttributeName: @1.5};

[attrStr addAttributes:attributes
                 range:[str rangeOfString:@"Sample"]];


また上記では addAttributes:range: メソッドを使用して複数の属性と値を一度に指定しています。同じ範囲に対して適用する場合等に便利です。


パラグラフスタイル

NSParagraphStyleAttributeName を使用すると、パラグラフスタイル(NSParagraphStyleオブジェクト)を指定することができます。NSParagraphStyleはアライメントやハイフネーションを指定するためのプロパティを持っています。

// NSMutableParagraphStyleオブジェクト
NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];

// アラインメント
paragraph.alignment = NSTextAlignmentRight;

// ハイフネーション
paragraph.hyphenationFactor = 0.9;

// パラグラフスタイル
[attrStr addAttribute:NSParagraphStyleAttributeName
                value:paragraph
                range:NSMakeRange(0, [attrStr length])];


hyphenationFactor には0.0〜1.0の値を指定することができ、0.0でハイフネーション(行末で切れる単語をハイフンで繋ぐ)なし、1.0で常にハイフネーションを試みる設定となります。


NSAttributedStringを使用可能なUIKitのクラス

UILabel, UITextView, UITextFieldの、 attributedText プロパティ以外にも、NSAttributedStringをセットできるプロパティ/メソッドがいくつかのUIKitのクラスに追加されています。


※いずれも要iOS6以上


UIButton

- (void)setAttributedTitle:(NSAttributedString *)title forState:(UIControlState)state


UIPickerView

- (NSAttributedString *)pickerView:(UIPickerView *)pickerView
             attributedTitleForRow:(NSInteger)row
                      forComponent:(NSInteger)component


UIRefreshControl

@property (nonatomic, retain) NSAttributedString *attributedTitle


UITextField

@property(nonatomic,copy) NSAttributedString *attributedPlaceholder