iOS
UILabel
Swift

UILabelの高さ計算時に気をつけること

More than 1 year has passed since last update.

はじめに

テキスト量によって、ラベルの高さ計算をしてラベルの高さの制約をセットする事がありますよね。

boundingRectメソッドで高さ計算できます。
ラベルの横幅、高さを指定します。

//UILabelにAttributedTextをセットして高さ計算
let boundingRect = label.attributedText!.boundingRect(with: CGSize.init(width: label.bounds.size.width,
                             height: CGFloat.greatestFiniteMagnitude),
                             options: .usesLineFragmentOrigin, context: nil)

問題

上記で計算した高さを持って、ラベルの高さの制約を設定したけど、
ラベルの上下に余計なスペースができてしまったり、高さが足りなくて見切れたりという事があります。
iPhone5だとうまく行くけど、iPhone6だとうまくいかないーなんて事があります。

原因

大抵の原因は、計算時の「横幅が正しくない」です。
print文などで、出力して確認してみてください。

計算時のラベルのwidthが、AutoLayout適用前のwidth、
つまりStoryboard上に置いたUILabelのwidthになっていたりします。
なので、StoryboardのViewControllerのサイズと違うデバイスサイズで見るとうまくいかなかったりします。

計算前にAutoLayoutを適用させる

まず最初にやる事は、viewにAutoLayoutを適用させます。

override func viewDidLoad() {
    super.viewDidLoad()
    self.view.layoutIfNeeded()

    //何らかの処理
}

viewやviewのsubViewsの制約が適用されて正しい横幅になります。

ただ、UITableViewCell上に置いたラベルの高さ計算の場合、これだけではだめで、
セルの横幅も設定してあげます。
tableViewの以下のデリゲートメソッドで、セルのframeをセットします。

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

 let commentCell:CommentCell =   tableView.dequeueReusableCellWithIdentifier("CommentCell") as! CommentCell
 //セルに正しい横幅を設定する 
 commentCell.frame = CGRectMake(0,0, self.tableView.width, commentCell:commentCell.frame.height)
 //セルを更新する
 commentCell.configure()

}

セルの横幅が正しい値でセットできたら、セルの更新メソッドなどの最初に
self.layoutIfNeededを実行してください。

//カスタムセルの更新メソッド 実際は引数にラベルに表示する文字列などのデータを渡す
func configure() {
 //セルの横幅が正しい状態で、AutoLayoutを適用する
 self.layoutIfNeeded()

 //ラベルの横幅が正しくなるので、この後高さ計算を行い、ラベルの制約を更新する

}

セルのsubviewであるラベルなどにAutoLayout適用後の正しいwidthがセットされて、
ラベルの横幅が正しい値になります。
boundingRectメソッドに指定する横幅が正しくなり、
高さ計算が期待した値になります。

まとめ

ラベルの高さ計算がうまくいかない時の確認事項とやる事

  1. 計算時のwidth(ラベルの横幅)が正しいかを確認
  2. widthが期待している値と違ったら、ラベルの親ViewにAutoLayoutを適用させる
  3. TableViewCell上のラベルの場合は、セルに正しいwidthを指定しつつ、AutoLayoutを適用する

以上、ラベルの高さ計算時にうまく行かなくて困った時は、
まずラベルの横幅を確認してみてください。