前書き
基本的に、StoryboardでUILabelを設置して高さの制約をつけなければ文章の長さに応じて自動的に高さが調整されます。
ただ、状況に応じてはUILabelの高さを能動的に算出したくなります。
例えば
・UITableViewCellやUICollectionViewCellの高さを先に計算したい
・標準以外のフォント(ヒラギノなど)で「g」や「q」を含む英文を表示する
※ 自動の高さ調節に任せると文字の下端が切れてしまうので高さの制約をつけて計算結果を設定する必要があります。
計算方法
いろいろな方法を試しましたが、以下の形が一番シンプルでした。
適当な名前でUILabelのカテゴリを作成して、そこに追加します。
参考 : CoreText ヒラギノフォント(日本語)で正確に描画サイズを取得する
UILabel+calc
+ (float)cal_getDescentFromUIFont:(UIFont *)font {
CTFontRef fontRef = CTFontCreateWithName((CFStringRef) font.fontName, font.pointSize, NULL);
float height = ceilf(CTFontGetDescent(fontRef));
CFRelease(fontRef);
return height;
}
- (CGRect)cal_rectForLabel {
if (self.text.length == 0) {
return CGRectZero;
}
CGSize size = [self sizeThatFits:CGSizeMake(self.frame.size.width, CGFLOAT_MAX)];
CGRect frame = self.frame;
frame.size.height = size.height + [UILabel cal_getDescentFromUIFont:self.font];
frame.size.width = size.width;
return frame;
}
使い方
例えばタイトルを表示するself.titleLabelと、その高さ制約である
NSLayoutConstraint *titleLabelHeightConstraint がある場合。
self.titleLabelHeightConstraint.constant = [self.titleLabel cal_rectForLabel].size.height
あとがき
当初はboundingRectWithSize:options:attributes:context
を使ってこの関数を作ってはいたんですがParagraphStyleで指定したLineHeightなどがうまく反映されなかったんだったかな? 何かしら問題が出たので結局こういった形に落ち着きました。
結局sizeToFitなどの関数を使ったほうが安定しますね。