自動レイアウトを使用して動的テーブルビューセクションヘッダーの高さを取得することは可能ですか?


112

iOS 8の新機能。行の推定高さを設定するだけで100%動的なテーブルビューセルを取得し、自動レイアウトを使用してセル内の要素をレイアウトできます。コンテンツの高さが増加すると、セルの高さも増加します。これは非常に便利です。テーブルビューのセクションヘッダーでも同じことを成し遂げることができるのでしょうか。

缶1は、例えば、作成UIView中をtableView:viewForHeaderInSection:追加し、UILabelサブビューを、ビューに対してラベルの自動レイアウトの制約を指定して、ラベルの内容に合わせて高さがビューの増加を持って、実装することなくtableView:heightForHeaderInSection:

viewForHeaderInSection状態のドキュメント:「このメソッドは、tableView:heightForHeaderInSection:も実装されている場合にのみ正しく機能します。」iOS 8で変更があったかどうかは聞いていません。

それができない場合、この動作を模倣する最良の方法は何ですか?

回答:


275

これは可能です。これは、iOS 8に実装された動的セルの高さに加えて新しいものです。

とても簡単です。これを追加するだけですviewDidLoad

self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
self.tableView.estimatedSectionHeaderHeight = 25;

次にviewForHeaderInSection、自動レイアウトをオーバーライドして使用し、ビュー内の要素を適切に見えるように制約します。それでおしまい!実装する必要はありませんheightForHeaderInSection。また、実際sectionHeaderHeightに記載する必要もありません。わかりやすくするために追加しました。

iOS 11では、セルとヘッダー/フッタービューはデフォルトで推定高さを使用することに注意してください。行うべき唯一のことは、システムに何を期待すべきかをよりよく知らせるために、推定された高さを提供することです。デフォルト値はですUITableViewAutomaticDimensionが、可能であれば平均高さであるより良い推定値を提供する必要があります。


3
それが機能するのであればそれはすばらしいことですが、ドキュメントはそれについて言及しておらず、正しく思い出せばWWDCセッションもしませんでした。ドキュメントでUITableViewAutomaticDimensionは、「この定数をtableView:heightForHeaderInSection:or tableView:heightForFooterInSection:で返す場合、or UITableViewから返される値に適合する高さを使用します(タイトルがでない場合)」。tableView:titleForHeaderInSection:tableView:titleForFooterInSection:nil
Aaron Brager、2015

28
これは私にはうまくいきませんでした。セクションヘッダーで高さを自動的に計算できましたが、セクションのセルと重なっています。xibファイルを使用してヘッダービューを設定し、インターフェイスビルダーで制約を設定しています。それは私の問題ですか?制約をどこで作成していますか?ありがとう!
CoBrA2168

5
ここで約束されているのはサンプルコードです:github.com/ebetabox/DynamicCellSectionHeight
PakitoV

10
ここでのもう1つの重要なポイントは、テーブルのセルがセクションで機能するように、自動高さ(UITableViewAutomaticDimension)計算用に構成する必要があることです。
Bob Spryn

9
あなたは持っている必要がありますestimatedSectionHeaderHeighttableView:estimatedHeightForHeaderInSection:sectionHeaderHeighttableView:heightForHeaderInSection:。さらに、デリゲートメソッドを使用している場合、推定値(完全に文書化されていない動作)に対して1.00より大きい値を返す必要があります。それ以外の場合、高さのデリゲートは呼び出されず、デフォルトのテーブルビューヘッダーの高さが使用されます。
Vadoff

29

これはestimatedSectionHeaderHeight、テーブルビューにを設定する(または返す)ことで実現できます。

を設定した後にセクションヘッダーがセルと重なってestimatedSectionHeaderHeightいる場合は、estimatedRowHeightも使用していることを確認してください。

(2番目の段落には、一部のコメントを見逃している可能性のあるすべてのコメントを読んだ後に見つけることができる問題への回答が含まれているため、この回答を追加します。)


1
おかげで、estimatedRowHeightこれを魅力のように設定した後:)
sz ashik '

1
これは、行にUITableViewAutomaticDimensionを使用していない場合でも当てはまります。1時間節約してくれてありがとう。
Ryan Romanchuk

14

ヘッダーの高さがゼロになるまで同じ問題が発生しましたが、のデリゲートに固定の高さを指定しない限りheighForHeaderInSection

含む多くのソリューションを試してみました

self.tableView.sectionHeaderHeight = UITableView.automaticDimension
self.tableView.estimatedSectionHeaderHeight = 73

しかし、何もうまくいきませんでした。私の細胞も適切な自動レイアウトを使用していました。行は次のコードを使用して動的に高さを変更していましたが、セクションヘッダーは変更していませんでした。

self.tableView.estimatedRowHeight = 135
self.tableView.rowHeight = UITableView.automaticDimension

修正は非常に単純で奇妙ですが、の1行のコードの代わりにデリゲートメソッドを実装する必要がestimatedSectionHeaderHeightありsectionHeaderHeight、私の場合は次のようになります。

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    UITableView.automaticDimension
}

func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
    73
}

11

スウィフト4+

動作中(100%テスト済み)

コンテンツに基づいて動的な高さのセクションと行の両方が必要な場合は、以下のコードを使用できます。

viewDidLoad()で次の行を記述します。

    self.globalTableView.estimatedRowHeight = 20
    self.globalTableView.rowHeight = UITableView.automaticDimension

    self.globalTableView.sectionHeaderHeight =  UITableView.automaticDimension
    self.globalTableView.estimatedSectionHeaderHeight = 25;

これで、UITableView Delegateメソッドを使用して行の高さとセクションの高さを設定しました。

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
   {
       return UITableView.automaticDimension
   }
   func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {

       return UITableView.automaticDimension

   }

この素晴らしい答えへのメモ2020年以降は、viewDidLoadの4つのプロパティのみを使用しても問題ないようです。
Fattie

この素晴らしい答えへのメモ2020年の時点では、推定高さ(たとえば20程度)を示す2つの「役に立たない」線が必要です。
Fattie

6

私は試した

self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
self.tableView.estimatedSectionHeaderHeight = 25;

しかし、複数行ラベルのあるヘッダーのサイズは正しくありませんでした。私の問題を解決するためにこれを追加しました:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    // Recalculates height
    tableView.beginUpdates()
    tableView.endUpdates()
}

データ・ソース関数を定義しないtableView:estimatedHeightForHeaderInSectionと、tableView:heightForHeaderInSection代わりのviewDidLoadで定義します。
キースYeoh

設定estimatedSectionHeaderHeightが必要なのはiOS 11以下のみです
doctorBroctor

1

私の場合:

  1. プログラムで設定しないでください

self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension

  1. ストーリーボードに設定すると機能しません

  2. オーバーライドがheightForHeaderInSection 機能しました

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return UITableViewAutomaticDimension
}

テスト環境:

  • Mac OS 10.13.4
  • XCodeバージョン9.4.1
  • シミュレーターiPhone 8 Plus

0

はい、うまくいきます。以下のようにさらに変更を加える必要があります。

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let label = UILabel()

    label.numberOfLines = 0
    label.text          = my own text

    return label
}

-2

iuriimozの 回答を変更しまし。ただviewWillAppearメソッドを置き換えました:

tableView.sectionHeaderHeight = UITableViewAutomaticDimension
tableView.estimatedSectionHeaderHeight = 25


override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    // Recalculates height
    tableView.layoutIfNeeded() 
}

また、tableView.layoutIfNeeded()を

override func viewDidAppear(_ animated: Bool) {

    super.viewDidAppear(animated)
    tableView.layoutIfNeeded()
}

iOS 10の場合

tableView.beginUpdates()
tableView.endUpdates()

viewWillAppearに「フェード」アニメーション効果を持たせる

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.