UITableView: viewForHeaderInSection: не вызывается во время reloadData:

Я установил tableview с правильными связями делегирования и datasource.. метод reloadData вызывает метод data и delegate, за исключением viewForHeaderInSection:.

Почему это так?

Ответ 1

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

Ответ 2

Хитрость в том, что эти два метода принадлежат разным протоколам UITableView: tableView:titleForHeaderInSection: - это метод протокола UITableViewDataSource, где tableView:viewForHeaderInSection принадлежит UITableViewDelegate.

Это значит:

  • Если вы реализуете методы, но назначаете себя только как dataSource для UITableView, ваш Реализация tableView:viewForHeaderInSection будет игнорироваться.

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

Я также попытался удалить tableView:heightForHeaderInSection:; это работало нормально и, похоже, не влияло на вышеуказанные процедуры. Но в документации сказано, что для правильной работы tableView:viewForHeaderInSection требуется; поэтому, чтобы быть в безопасности, разумно это реализовать.

Ответ 3

@rmaddy неправильно это правило дважды: на самом деле tableView:viewForHeaderInSection: не требует, чтобы вы также реализовали tableView:heightForHeaderInSection:, а также отлично назвать оба titleForHeader и viewForHeader. Я правильно сформулирую правило для записи:

Правило просто в том, что viewForHeader не будет вызываться, если вы каким-то образом не дадите заголовку высоту. Вы можете сделать это в любой комбинации из трех способов:

  • Внедрить tableView:heightForHeaderInSection:.

  • Задайте таблицу sectionHeaderHeight.

  • Вызов titleForHeader (это как-то дает заголовку высоту по умолчанию, если в противном случае она не имеет).

Если вы ничего не делаете, у вас не будет заголовков, а viewForHeader не будет вызываться. Это потому, что без высоты, среда выполнения не будет знать, как изменить размер представления, поэтому не стоит просить об этом.

Ответ 4

Предоставление значений estimatedSectionHeaderHeight и sectionHeaderHeight исправило мою проблему. например., self.tableView.estimatedSectionHeaderHeight = 100 self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension

Ответ 5

Отправляя ответ rmaddy, я пытался скрыть представление заголовка и возвращал 0.0f для "tableView: heightForHeaderInSection" и 0 height View из tableView:viewForHeaderInSection.

После перехода от return 1.0f в return 0.0f в tableView:heightForHeaderInSection метод делегирования tableView:viewForHeaderInSection действительно был вызван.

Оказывается, мой желаемый эффект работает без использования "tableView: heightForHeaderInSection"; но это может быть полезно для других, у которых возникла проблема с вызовом метода делегата tableView: heightForHeaderInSection.

Ответ 6

Вы должны реализовать tableView:heightForHeaderInSection: и установить высоту для заголовкa > 0.

Этот метод делегата совпадает с методом viewForHeaderInSection:.

Надеюсь, это поможет.

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

Ответ 7

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

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

Из комментариев в UITableView.h:

Возврат этого значения из tableView:heightForHeaderInSection: или tableView:heightForFooterInSection: приводит к высоте, которая соответствует значению, возвращаемому из tableView:titleForHeaderInSection: или tableView:titleForFooterInSection:, если заголовок не равен нулю.

Ответ 8

У меня только что возникла проблема с заголовками, которые не показываются для 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, по крайней мере.

Ответ 9

Такая же проблема возникла у меня, но поскольку я использовал автоматический расчет высоты от xCode 9, я не могу дать никакого явного значения высоты, как указано выше. После некоторого эксперимента я получило решение, мы должны переопределить этот метод как,

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

Хотя у меня отмечен обе опции

  • Автоматический расчет высоты
  • Автоматическое вычисление расчетной высоты

из раскадровки, как говорит яблоко, но все же я получил эту странную ошибку.

Обратите внимание. Эта ошибка была показана только в версии IOS-10 не в версии IOS-11. Возможно, это ошибка от xCode. Благодаря

Ответ 10

Вот что я нашел (Swift 4) (благодаря этому комментарию на другой вопрос)

Независимо от того, использовал ли я titleForHeaderInSection или viewForHeaderInSection - они не вызывались при прокрутке таблицы и при загрузке новых ячеек, но любые варианты шрифтов, которые я сделал для headerView textLabel, появлялись только в том, что первоначально было видно при загрузке., а не как стол прокручивался.

Исправление было: DisplayDheplayView:

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

Ответ 11

В моем случае я создал вид заголовка, используя UITableviewCell и возвращая ячейку в viewForHeaderInSection следующим образом

return cell

изменил это на

return cell.contentView 

работал на меня.

Ответ 12

Иногда установка tableview.delegate или datasource = nil в методах viewWillAppear: или viewDidAppear: может вызвать эту проблему. Не забудьте сделать это...

Ответ 13

Я вырезал и вставлял следующие два метода из проекта Swift 2 в мой проект 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
}