UITableView : viewForHeaderInSection: not called during reloadData:
The use of tableView:viewForHeaderInSection:
requires that you also implement tableView:heightForHeaderInSection:
. This should return an appropriate non-zero height for the header. Also make sure you do not also implement the tableView:titleForHeaderInSection:
. You should only use one or the other (viewForHeader
or titleForHeader
).
The trick is that those two methods belong to different UITableView
protocols: tableView:titleForHeaderInSection:
is a UITableViewDataSource
protocol method, where tableView:viewForHeaderInSection
belongs to UITableViewDelegate
.
That means:
If you implement the methods but assign yourself only as the
dataSource
for theUITableView
, yourtableView:viewForHeaderInSection
implementation will be ignored.tableView:viewForHeaderInSection
has a higher priority. If you implement both of the methods and assign yourself as both thedataSource
and thedelegate
for theUITableView
, you will return the views for section headers but yourtableView:titleForHeaderInSection:
will be ignored.
I have also tried removing tableView:heightForHeaderInSection:
; it worked fine and didn't seem to affect the procedures above. But the documentation says that it is required for the tableView:viewForHeaderInSection
to work correctly; so to be safe it is wise to implement this, as well.
@rmaddy has misstated the rule, twice: in reality, tableView:viewForHeaderInSection:
does not require that you also implement tableView:heightForHeaderInSection:
, and also it is perfectly fine to call both titleForHeader
and viewForHeader
. I will state the rule correctly just for the record:
The rule is simply that viewForHeader
will not be called unless you somehow give the header a height. You can do this in any combination of three ways:
Implement
tableView:heightForHeaderInSection:
.Set the table's
sectionHeaderHeight
.Call
titleForHeader
(this somehow gives the header a default height if it doesn't otherwise have one).
If you do none of those things, you'll have no headers and viewForHeader
won't be called. That's because without a height, the runtime won't know how to resize the view, so it doesn't bother to ask for one.
Giving estimatedSectionHeaderHeight
and sectionHeaderHeight
values fixed my problem.
e.g.,
self.tableView.estimatedSectionHeaderHeight = 100
self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension
Going off rmaddy 's answer, I was trying to hide the Header view and was returning 0.0f for "tableView:heightForHeaderInSection" and a 0 height View from tableView:viewForHeaderInSection
.
After changing from return 1.0f
to return 0.0f
in tableView:heightForHeaderInSection
, the delegate method tableView:viewForHeaderInSection
was indeed called.
Turns out my desired effect works without having to use "tableView:heightForHeaderInSection"; but this may be useful to others who are having an issue getting "tableView:heightForHeaderInSection" delegate method called.