your3i’s blog

iOSエンジニア。頑張る⚉

Intrinsic content sizeを使ってtableviewのdynamic heightを対応

Intrinsic content sizeとは

  • Auto Layout 機能の一部
  • UIViewのintrinsicContentSizeプロパティ
  • constraintが設定されてない場合、intrinsicContentSizeが代わりレイアウトの計算に使われる
  • UILabel, UIButtonみたいに、Viewのいろんな中身を適切に表示するために必要なサイズのこと
  • ほかに参考になれるリンク:

Auto Layout Guide: Views with Intrinsic Content Size

What is a view’s intrinsic content size? - free Swift 4 example code and tips

使い方

UILabel, UIButtonみたいなUIViewのsubclassたちはもうintrinsicContentSizeをいい感じに管理している。でもほかに管理してないsubclassたちもいっぱいある。例えばUITableView。

intrinsicContentSizeをいい感じに対応するために?

もとのビュークラスを継承して、intrinsicContentSizeをoverrideして正しいintrinsicContentSizeを返す。

tableviewのdynamic heightを対応

⬇️を使うことで、tableviewがcontentSizeによって自動で伸びる。そして、必要によって限界値を設定する。

class SelfResizingTableView: UITableView {

    // 限界値プロパティ
    var maxHeight: CGFloat = .greatestFiniteMagnitude

    override var contentSize: CGSize {
        didSet {
            // contentSizeが変わったから
            // invalidateIntrinsicContentSize()を呼び出して、intrinsicContentSizeの再計算をリクエスト
            invalidateIntrinsicContentSize()
        }
    }

    // intrinsicContentSizeを計算
    override var intrinsicContentSize: CGSize {
        let height = min(contentSize.height, maxHeight)
        return CGSize(width: contentSize.width, height: height)
    }
}

まとめ

Intrinsic content sizeを使うと、いろんなビューのruntime dynamic sizeを対応できる。UIStackViewと合わせて使うと、auto layoutの設定がかなり楽になる気がする。