UIKit - AutoLayoutを利用した高さ可変のTableHeaderViewをつくる

表題通りUITableViewのHeaderに高さ可変のHeaderViewをつくります。

TableHeaderViewの中にラベルか何かを表示させていて、
その文字列をレスポンスから引っ張ってきたりして設定するために、
高さを変えなければならない。そんな人向けの記事です。

まずTableHeaderViewをつくりましょう。

当たり前ですが、xibでもコードオンリーでもいいのでHeaderViewをつくりましょう。
その際、下辺が大きさに応じて変化させることができるような制約(Constraint)をつけましょう。 下はかんたんな例。 カスタムビューの最下端にラベルのボトムとの制約をつけています。

class MyTableHeaderView: UIView {

    var label: UILabel! = {

    }()

   override func updateConstraints() {
        super.updateConstraints()
        
        labelDescription.bottomAnchor.constraintEqualToAnchor(bottomView.bottomAnchor, constant: -16).active = true
    } 
}

UITableViewに設定しよう

以下の様な感じで設定してください。 ぼくは以下の処理をself.view.frameの大きさが決まった、viewDidLayoutSubviewsに書いています。
viewDidLayoutSubViewsは複数回呼ばれるので注意。

let headerView = MyTableHeaderView()
headerView.frame = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: デフォルトの高さ)

self.tableView.tableHeaderView = MyTableHeaderView()

高さ可変の処理

たとえば、ヘッダーに大量の文字列を入れなければならないとしましょう。
そのタイミングで以下のような処理を書きます。

if let tableHeaderView = self.tableView.tableHeaderView as? MyTableHeaderView {
    // 大量のテキストを設定
    tableHeaderView.label.text = "大量のテキスト"

    // テキスト入れた状態でAutolayoutによる高さの算出
    tableHeaderView.setNeedsLayout()
    tableHeaderView.layoutIfNeeded()
    let size = tableHeaderView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
                
    // 高さの再設定
    tableHeaderView.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height)

    // 再代入
    self?.tableView.tableHeaderView = tableHeaderView
}

おそらくこの方法でできるはずです。ではでは

参考: iOS7・iOS8の処理分岐なし!UITableViewのCellの高さをAutolayoutで自動計算する方法 - 株式会社エウレカ