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


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.