问题
I've set up the tableview with correct delegate and datasource linkages.. the reloadData method calls the datasource and the delegate methods except for viewForHeaderInSection:.
Why is that so?
回答1:
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).
回答2:
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
dataSourcefor theUITableView, yourtableView:viewForHeaderInSectionimplementation will be ignored.tableView:viewForHeaderInSectionhas a higher priority. If you implement both of the methods and assign yourself as both thedataSourceand thedelegatefor 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.
回答3:
@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.
回答4:
Giving estimatedSectionHeaderHeight and sectionHeaderHeight values fixed my problem.
e.g.,
self.tableView.estimatedSectionHeaderHeight = 100
self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension
回答5:
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.
回答6:
You should implement tableView:heightForHeaderInSection: and set the height for the header >0.
This delegate method goes along with the viewForHeaderInSection: method.
I hope this helps.
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 40;
}
回答7:
It's worth briefly noting that if your implementation of tableView:heightForHeaderInSection: returns UITableViewAutomaticDimension, then tableView:viewForHeaderInSection: will not be called.
UITableViewAutomaticDimension assumes that a standard UITableViewHeaderFooterView will be used that is populated with the delegate method tableView:titleForHeaderInSection:.
From comments in the UITableView.h:
Returning this value from
tableView:heightForHeaderInSection:ortableView:heightForFooterInSection:results in a height that fits the value returned fromtableView:titleForHeaderInSection:ortableView:titleForFooterInSection:if the title is not nil.
回答8:
I've just had an issue with headers not showing for iOS 7.1, but working fine with later releases I have tested, explicitly with 8.1 and 8.4.
For the exact same code, 7.1 was not calling any of the section header delegate methods at all, including: tableView:heightForHeaderInSection: and tableView:viewForHeaderInSection:.
After experimentation, I found that removing this line from my viewDidLoad made headers re-appear for 7.1 and did not impact other versions I tested:
// _Removing_ this line _fixed_ headers on 7.1
self.tableView.estimatedSectionHeaderHeight = 80;
… so, there seems to be some kind of conflict there for 7.1, at least.
回答9:
Same issue occured with me but as I was using automatic height calculation from xCode 9, I cannot give any explicit height value as mentioned above. After some experimentation I got solution, we have to override this method as,
-(CGFloat)tableView:(UITableView *)tableView
estimatedHeightForHeaderInSection:(NSInteger)section
{
return 44.0f;
}
Although I have checked both options
- Automatic Height Calculation
- Automatic Estimated Height Calculation
from storyboard as apple says, but still I got this weird error.
Please Note: This Error was shown only on IOS-10 version not on IOS-11 version. Maybe it's a bug from xCode. Thanks
回答10:
Here's what I've found (Swift 4) (thanks to this comment on another question)
Whether I used titleForHeaderInSection or viewForHeaderInSection - it wasn't that they weren't getting called when the tableview was scrolled and new cells were being loaded, but any font choices I made for the headerView's textLabel were only appearing on what was initially visible on load, and not as the table was scrolled.
The fix was 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)
}
}
回答11:
In my case I have created header view using UITableviewCell and returning the cell in viewForHeaderInSection like this
return cell
changed this to
return cell.contentView
Worked for me.
回答12:
In my case
viewForHeaderInSection
was implemented in a derived class far far away that was not bothering to daisy into superclass.
回答13:
Sometimes setting tableview.delegate or datasource = nil in the viewWillAppear: or viewDidAppear: methods can cause this issue. Make sure not to do this...
回答14:
I had cut & paste the following two methods from a Swift 2 project into my Swift 3 project which were never called because in Swift 3 these methods must have "-" before the first parameter name.
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
}
来源:https://stackoverflow.com/questions/15078725/uitableview-viewforheaderinsection-not-called-during-reloaddata