読者です 読者をやめる 読者になる 読者になる

iOSアプリ開発の逆引き辞典

iPhone/iPadで使えるアプリ開発のTipsをまとめてみました

文字列を表示するサイズを求めるsizeWithFont:メソッドがiOS 7から非推奨になっているのでワーニングが出ないように置き換える

フォントを指定して、文字列が描画されるサイズを求めるのにiOS 6まではsizeWithFont:メソッドsizeWithFont:constrainedToSize:lineBreakMode:メソッドを使っていました。iOS 7ではこれらのメソッドの使用が非推奨になっています。

- (CGSize)sizeWithFont:(UIFont *)font;

- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size;
- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(NSLineBreakMode)lineBreakMode;

ベースSDKがiOS 7.0以上になっていて、これらのメソッドを使用した場合は以下のようなワーニングが表示されます。

'sizeWithFont:' is deprecated: first deprecated in iOS 7.0 - Use -sizeWithAttributes:

該当する箇所が少ない場合はsizeWithAttributes:メソッドboundingRectWithSize:options:attributes:context:メソッドに書き換えていけば良いのですが、多い場合は該当箇所を全て書き換えるのは大変です。

そこでメソッド名のお尻にExを付けたカテゴリNSString (Utilities)を用意して、引数をそのまま吸収させることにします。

@interface NSString (Utilities)

- (CGSize)sizeWithFontEx:(UIFont *)font;
- (CGSize)sizeWithFontEx:(UIFont *)font constrainedToSize:(CGSize)size;
- (CGSize)sizeWithFontEx:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(NSLineBreakMode)lineBreakMode;

@end

sizeWithFontEx:メソッドでは内部的にsizeWithAttributes:メソッドを使用し、sizeWithFont:constrainedToSize:lineBreakMode:メソッドでは内部的にboundingRectWithSize:options:attributes:attributes:context:メソッドを使用して、指定されたフォントを使った場合に表示される文字列のサイズを計算します。

#import "NSString+Utilities.h"

@implementation NSString (Utilities)

- (CGSize)sizeWithFontEx:(UIFont *)font
{
    NSDictionary *attributes = @{ NSFontAttributeName : font };
    return [self sizeWithAttributes:attributes];
}

- (CGSize)sizeWithFontEx:(UIFont *)font constrainedToSize:(CGSize)size
{
    return [self sizeWithFontEx:font constrainedToSize:size
                  lineBreakMode:NSLineBreakByWordWrapping];
}

- (CGSize)sizeWithFontEx:(UIFont *)font constrainedToSize:(CGSize)size
           lineBreakMode:(NSLineBreakMode)lineBreakMode
{
    NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
    style.lineBreakMode = lineBreakMode;
    style.alignment = NSTextAlignmentLeft;
    
    NSDictionary *attributes = @{
                                 NSFontAttributeName : font,
                                 NSParagraphStyleAttributeName : style
    };
    CGRect rect = [self boundingRectWithSize:size
                                    options:NSStringDrawingUsesLineFragmentOrigin
                                 attributes:attributes
                                    context:nil];
    return rect.size;
}