UITableView: viewForHeaderInSection: не викликається під час reloadData:


127

Я встановив табличний перегляд з правильними зв'язками делегатів та джерел даних .. метод reloadData викликає джерела даних та методи делегування, за винятком viewForHeaderInSection:.

Чому це так?


30
Чи heightForHeaderInSection:реалізовано?
7

Ви встановили значення для TableView sectionHeaderHeight?
Картер Медлін

Відповіді:


256

Використання tableView:viewForHeaderInSection:вимагає, щоб ви також реалізували tableView:heightForHeaderInSection:. Це має повернути відповідну ненульову висоту для заголовка. Також переконайтеся, що ви також не реалізуєте tableView:titleForHeaderInSection:. Вам слід використовувати лише те чи інше ( viewForHeaderабоtitleForHeader ).


3
Переконайтеся, що в підписі методу немає помилки. Один неправильний лист означатиме, що його не називатимуть. Перевірте також справу. Також переконайтеся, що ви повертаєте 0 з numberOfSections.
rmaddy

все правильно і компілюється правильно. Проблема, яку я хотів зрозуміти, стосується часу, коли метод називається .. tableView: viewForHeaderInSection викликається, коли таблиця збирається відображатися, а не як частина синхронізованого виконання [ tableview reloadData]
inforeqd

@maddy OMG Дякую, мені так глупо, що я створив свої екземпляри, але я не додав до свого масиву
додав Happiehappie

4
Ви можете мати обоє. viewForHeaderInSection: матиме перевагу над titleForHeaderInSection: Єдина вимога полягає в тому, щоб ви встановили оцінкуSectionHeaderHeight на своєму перегляді таблиці з чимось іншим, ніж 0, інакше viewForHeaderInSection: ніколи не зателефонують
romrom

Додаючи до коментаря @ romrom: якщо ви реалізували titleForHeaderInSection:і те, viewForHeaderInSection:і подання, повернене з останнього, є підкласом, UITableViewHeaderFooterViewтоді його textLabel.textавтоматично встановлюють у версію titleForHeaderInSection:рядка з усіма заповненнями. Щоб запобігти такій поведінці, не застосовуйте titleForHeaderInSection:та не використовуйте власну мітку замість успадкованої textLabel.
Ортвін Генц

40

Хитрість полягає в тому, що ці два методи належать до різних UITableViewпротоколів: tableView:titleForHeaderInSection:це UITableViewDataSourceметод протоколу, куди tableView:viewForHeaderInSectionналежитьUITableViewDelegate .

Це означає:

  • Якщо ви реалізуєте методи, але призначите себе лише як dataSourceдля UITableView, ваша tableView:viewForHeaderInSectionреалізація буде проігнорована.

  • tableView:viewForHeaderInSectionмає більш високий пріоритет. Якщо ви реалізуєте обидва способи і призначите себе як і як, dataSourceі delegateдля UITableView, ви повернете думки для заголовків розділів, але ваші tableView:titleForHeaderInSection:ігноруються.

Я також спробував видалити tableView:heightForHeaderInSection:; він працював нормально і, схоже, не впливав на вищезазначені процедури. Але документація говорить про те, що для tableView:viewForHeaderInSectionкоректної роботи вона потрібна ; щоб бути безпечним, розумно це також здійснити.


6
Ти зробив мій день!!! Забув призначити UITableViewDelegateна self, тому що я думав, що tableView:viewForHeaderInSectionце UITableViewDataSourceметод. Дякую!
denis631

1
"tableView: viewForHeaderInSection" не є життєво важливим. Важливо, що ти якось повертаєш висоту. Ви можете досягти цього через 1. оцінку або 2. твердо кодовану величину або 3. а, titleForHeaderяка має внутрішній розмір. Власний розмір обчислюється виходячи з сімейства шрифтів та розміру.
Мед

28

@rmaddy помилився з цим правилом двічі: насправді tableView:viewForHeaderInSection:це не вимагає, щоб ви також реалізували tableView:heightForHeaderInSection:, а також цілком чудово називати titleForHeaderіviewForHeader . Я правильно викладу правило лише для запису:

Правило просто таке, що viewForHeaderне буде називатися, якщо ви якось не надасте заголовку висоту. Це можна зробити будь-якою комбінацією трьох способів:

  • Реалізація tableView:heightForHeaderInSection:.

  • Встановіть таблицю sectionHeaderHeight.

  • Виклик titleForHeader(це якимось чином дає заголовку висоту за замовчуванням, якщо в іншому випадку його немає).

Якщо ви не зробите жодної з цих речей, у вас не буде заголовків і вам не дзвонять viewForHeader. Це тому, що без висоти час виконання не знатиме, як змінити розмір виду, тому запитувати його не потрібно.


З Документів для tableView:viewForHeaderInSection:: "Цей метод працює правильно лише тоді, коли tableView:heightForHeaderInSection:він також реалізований."
rmaddy

1
Чудово. Що говорять документи, вони кажуть. Тепер експериментуйте. Факти такі, як я вже зазначив.
мат

А як можна мати і те, titleForHeaderInSectionі viewForHeaderInSection? Перегляд таблиці буде викликати лише одне з двох (я забуваю, який має перевагу в даний момент).
rmaddy

1
Насправді є ще один фрагмент головоломки, який іноді viewForHeader називається без жодного з цих трьох способів призначення висоти. У мене це сталося, коли мені viewForHeaderдзвонили, і заголовки виявлялися просто чудово, поки одного дня, не змінивши з мого боку, вони цього не зробили . Ось тоді я почав експериментувати, щоб виявити, які мінімальні вимоги viewForHeaderпотрібно викликати. І тепер я знаю. А тепер так і ти.
матовий

2
@texas Ні, я не роблю xamarin. Якщо додати ще один рівень опосередкованості поверх какаових каркасів, це просто змусить мою голову вибухнути. :)
мат

20

Давання estimatedSectionHeaderHeightта sectionHeaderHeightцінності вирішили мою проблему. наприклад, self.tableView.estimatedSectionHeaderHeight = 100 self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension


Моя проблема розпочалася після оновлення до Swift 3.1. Це рішення зафіксувало його.
zevij

@pbuchheit Apple Docs каже, що це доступно з iOS 7.0+, перегляньте тут, developer.apple.com/documentation/uikit/uitableview/…
Шарух Мастан

@Sharukh Mastan Схоже, ти прав. Чомусь я отримував попередження, коли я намагався використовувати це майно, але воно пішло після чистого складання.
pbuchheit

7

Виходячи з відповіді rmaddy, я намагався приховати перегляд заголовка і повертав 0,0f для "tableView: heightForHeaderInSection" та 0 View висоти від tableView:viewForHeaderInSection.

Після зміни з return 1.0fна return 0.0fна tableView:heightForHeaderInSection, tableView:viewForHeaderInSectionдійсно викликали метод делегата .

Виявляється, мій бажаний ефект працює без необхідності використання "tableView: heightForHeaderInSection"; але це може бути корисно іншим, у кого виникають проблеми з отриманням методу делегата "tableView: heightForHeaderInSection".


5

Ви повинні реалізувати tableView:heightForHeaderInSection:та встановити висоту заголовка> 0.

Цей метод делегата йде разом із viewForHeaderInSection:методом.

Я сподіваюся, що це допомагає.

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
         return 40;
}

Ви перевірили, що ваша відповідь насправді працює? Якщо ви уважно читаєте, то зазначено, що спочатку викликається viewForHeaderInSection. Це не викликається лише тоді, коли таблиця перезавантажена!
Карліс

5

Варто коротко зазначити, що якщо ваша реалізація tableView:heightForHeaderInSection:повертається UITableViewAutomaticDimension, то tableView:viewForHeaderInSection:не буде викликана.

UITableViewAutomaticDimensionпередбачає, що UITableViewHeaderFooterViewбуде використаний стандарт , заповнений методом делегата tableView:titleForHeaderInSection:.

З коментарів у UITableView.h:

Повернення цього значення з tableView:heightForHeaderInSection:або tableView:heightForFooterInSection:призводить до висоти, що відповідає значенню, поверненому з tableView:titleForHeaderInSection:або tableView:titleForFooterInSection:якщо заголовок не є нульовим.


1
якщо ви встановите estimatedSectionHeaderHeightдеяке значення, tableView:viewForHeaderInSectionбуде викликано (подібно до того, як працюють автоматичні розміри рядків)
GreatWiz

Цікаво, дякую. Ще в 7.1 ця тонкість орієнтовної висоти була важливою для комірок , тому, можливо, це стосувалося і заголовків - але це зараз не дуже актуально!
Бенджон

3

Щойно у мене виникла проблема з тим, що заголовки не відображаються для iOS 7.1 , але добре працює з пізнішими версіями, які я протестував, явно з 8.1 та 8.4.

Для точно такого ж коду 7.1 взагалі не викликали жодного із методів делегування заголовка розділу, включаючи: tableView:heightForHeaderInSection:таtableView:viewForHeaderInSection: .

Після експерименту я виявив, що видалення цього рядка з моїх viewDidLoadзроблених заголовків знову з’являється для 7.1 і не впливає на інші тестовані версії:

// _Removing_ this line _fixed_ headers on 7.1
self.tableView.estimatedSectionHeaderHeight = 80;

… Тож, мабуть, існує якийсь конфлікт там, принаймні 7,1.


3

У мене сталася та сама проблема, але, коли я використовував автоматичний розрахунок висоти з xCode 9 , я не можу дати явного значення висоти, як було зазначено вище. Після деяких експериментів я отримав рішення , ми повинні перекрити цей метод,

-(CGFloat)tableView:(UITableView *)tableView 
         estimatedHeightForHeaderInSection:(NSInteger)section
{
      return 44.0f;
}

Хоча я перевірив обидва варіанти

  1. Автоматичний розрахунок висоти
  2. Автоматичний розрахунок розрахункової висоти

від розкадровки , як яблуко говорить, але до сих пір я отримав цю дивну помилку.

Зверніть увагу : Ця помилка була показана лише у версії IOS-10, а не у версії IOS-11 . Можливо, це помилка від xCode. Дякую


0

Ось що я знайшов ( Swift 4 ) (завдяки цьому коментарю до іншого питання)

Я використовував заголовокForHeaderInSection чи viewForHeaderInSection - це було не те, що вони не викликали, коли проглядав таблицю та пропускали нові комірки, але будь-який вибір шрифту, який я зробив для textLabel headerView, відображався лише на тому, що спочатку було видно при завантаженні , а не так, як таблиця прокручувалася.

Виправлення було willDisplayHeaderView:

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    if let header = view as? UITableViewHeaderFooterView {
        header.textLabel?.font = UIFont(name: yourFont, size: 42)
    }
}

0

У моєму випадку я створив подання заголовка, використовуючи UITableviewCellта повертаючи клітинку viewForHeaderInSectionтак

return cell

змінив це на

return cell.contentView 

Працювали для мене.


0

У моєму випадку

viewForHeaderInSection

був реалізований у похідному класі далеко, далеко не заважаючи ромашці перетворюватися в суперклас.


0

Причина, через яку viewForHeaderInSectionне дзвонять, - одна з двох причин:

Або ви не налаштували свою UITableViewDelegate, або UITableViewDelegateнеправильно налаштували .


0

У моєму випадку це було через те, що я не реалізував:

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat

-1

Іноді встановлення tableview.delegateабо datasource = nilв методах viewWillAppear:або viewDidAppear:методах може викликати цю проблему. Переконайтеся, що цього не робити ...


-1

У мій проект Swift 3 я вирізав і вставив наступні два методи, які ніколи не викликали, тому що в Swift 3 ці методи повинні мати "-" перед першою назвою параметра.

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

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

    let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: B2BTrolleyHeaderFooterView.reuseIdentifier) as! B2BTrolleyHeaderFooterView        
    return headerView
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.