Чи можливо отримати висоту заголовка розділу динамічного перегляду таблиці за допомогою автоматичного макета?


112

Нове в iOS 8, ви можете отримати 100% динамічні осередки перегляду таблиці, просто встановивши передбачувану висоту рядка, а потім розташуйте елементи в комірці за допомогою автоматичного макета. Якщо вміст збільшується у висоту, клітина також зростатиме у висоту. Це надзвичайно корисно, і мені цікаво, чи можна виконати такий самий подвиг для заголовків розділів у таблиці?

Чи можна, наприклад, створити 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:або tableView:heightForFooterInSection:, UITableViewвикористовуєте висоту, яка відповідає значенню, поверненому з tableView:titleForHeaderInSection:або tableView:titleForFooterInSection:(якщо заголовок немає nil)".
Аарон Брагер

28
Це не спрацювало для мене. Заголовок мого розділу міг автоматично обчислити висоту, але він перекриває комірки в розділі. Я налаштовую свій вид заголовка за допомогою файлу xib і встановлюю свої обмеження в конструкторі інтерфейсів. Це моя проблема? Де ви, хлопці, створюєте обмеження? Дякую!
CoBrA2168


10
Ще одним ключовим моментом тут, комірки таблиці також повинні бути налаштовані для автоматичного обчислення висоти (UITableViewAutomaticDimension), щоб вона працювала над секціями.
Боб Сприн

9
Ви повинні мати estimatedSectionHeaderHeightабо tableView:estimatedHeightForHeaderInSection:AND sectionHeaderHeightабо tableView:heightForHeaderInSection:. Крім того, якщо ви використовуєте методи делегування, ви повинні повернути значення, що перевищує 1,00 для оцінки (повністю бездокументоване поведінка), інакше делегат по висоті НЕ буде викликаний, і буде використана висота заголовка подання таблиці за замовчуванням.
Вадофф

29

Це можна досягти, встановивши (або повернувши) вказівку estimatedSectionHeaderHeightна своєму столі.

Якщо заголовок розділу перекриває ваші клітини після налаштуванняestimatedSectionHeaderHeight , переконайтеся, що ви також використовуєте estimatedRowHeight.

(Я додаю цю відповідь, тому що другий абзац містить відповідь на питання, яке можна знайти, прочитавши всі коментарі, які деякі можуть пропустити.)


1
Дякую, після налаштування estimatedRowHeightце працює як шарм :)
sz ashik

1
Це справедливо, навіть якщо ви НЕ використовуєте UITableViewAutomaticDimension для рядків. Дякуємо, що врятували мене годину.
Райан Романчук

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.
Fattie

Зверніть увагу на цю чудову відповідь. Станом на 2020 рік вам потрібні дві "марні" лінії, що дають орієнтовну висоту (скажімо, 20 або близько того).
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.
Кіт Йох

Я встановив, що налаштування 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

Я змінив відповідь іуріімоз . Щойно замінений метод 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 для мене

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.