UILabelの実体があるときはsizeThatFitsを使えばいいのだけど、実体がない時にあらかじめサイズを計算したい時がある。代表的なのはUITableViewDelegateのheightForRowAtで、UILabelを含む可変するセルの高さを計算したい時。
この関数を使うと文字列からサイズ計算できるけど、UILabel#sizeThatFitsと結果が微妙に異なる。
(string as NSString).boundingRect(
with: CGSize(width: 300, height: 1000),
options: [NSStringDrawingOptions.usesLineFragmentOrigin, NSStringDrawingOptions.usesFontLeading],
attributes: [
NSAttributedStringKey.font: font,
],
context: nil).size
またUILabelでnumberOfLines = 3とか3行だけ表示したいと行ったときはどう計算するべきなのか。
UILabelのオブジェクトをその場で作ってsizeThatFitsを呼び出せばいいけど、表示しないViewを一時的に作ることになんとなく抵抗があった。でも、よく考えたらそんな悩むことではなく、UILabelを1つ作って保持して、そのsizeThatFitsを呼び出せばいいのでした。
extension UILabel {
static let shared: UILabel = UILabel()
}
UILabel.shared.text = "hoge"
UILabel.shared.numberOfLines = 3
let size = UILabel.shared.sizeThatFits(CGSize(width: 300, height: 1000))