見つけたときあまりにも嬉しくて、それと同時にネットの情報に苛立ちを覚えたので、自分と同じ微妙なバグに悩まされている方が少しでも減ればと思い共有しときます。
iOSで描画せずにテキストの描画領域を得たい場合に利用する NSString.boundingRectWithSize:options:attributes:context:
ですが、戻り値CGRect
のheight
はそのまま使うとNSAttributedString
など属性付きの場合にズレが生じます。 通常の加工なしでは起きないのですが、実際のアプリでは装飾無しのプレーンなラベルだけのアプリなんてほぼないです。
受け取ったCGRect
はceil
で切り上げしてください。
Appleの API Reference にも書いてるのですが、
This method returns fractional sizes (in the size component of the returned CGRect); to use a returned size to size views, you must raise its value to the nearest higher integer using the ceil function.
Google大先生!
このメソッドは、(返されるCGRectのサイズコンポーネント内の)分数サイズを返します。 返されたサイズをビューのサイズに使用するには、ceil関数を使用してその値を最も近いより高い整数に上げる必要があります。
実際に ceil
で切り上げると、最後の1行が描画されない問題が解決しました。
それでもUILabel
でズレる場合(追記)
それでもズレるケースがありました。
その場合、boundingRectWithSize
ではなく UILabel.preferredMaxLayoutWidth
が古いサイズのままになっていることが原因で、実際の描画時の高さ計算がズレが生じて、 boundingRectWithSize
とは異なる高さになってる場合があります。