UITableView Not Respecting heightForHeaderInSection/heightForFooterInSection?
cocoa-touch, iphone
Solution
In a "grouped" UITableView on the iPhone it will still render a minimum height for header and footer, effectively ignoring your code to set it to zero. It is not linked to the XIB default.
This is because a zero height section header or footer would look very odd. Therefore Apple has decreed that a header height cannot be set to 0. And therefore multiple "empty" sections will render oddly as per your screenshot.
I'm afraid it's all because you're going the wrong way about clearing the header size when there are no data rows; instead you should not be calling any methods for empty sections. It is a bad technique because essentially the iPhone is having to call more methods than it ought to, and also you render more headers than you want to (usually - sometimes people want to leave the blank headers there, for example for drag and drop).
So, for example, let's imagine that you have a number of sections, but only some of them have more than one row in (perhaps based on user settings/filters).
The wrong way of implementing it is:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return totalNumberOfPossibleSections;
}
and then for each section you have no result for:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (![section hasRow]) return 0;
}
and
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
if (![section hasRow]) return 0.0f;
}
The correct way of implementing it is:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return numberOfSectionsWhichHaveAtLeastOneRowInThem;
}
and then each section will have at least one result. That way, sections with no data aren't even rendered, methods aren't even called for them. Note: my two variable names are made up to convey what they'll contain! They're not special Apple variables...
Hope that helps!
Problem
I have a UITableView where in some instances, certain sections have zero rows. My goal is that when this is true, I don't want any wasted space in the table view, it should look like there's no data. The problem I'm having is with the header and footer for the sections, which are showing even if there's no row and despite me overriding the delegate method to return 0.0f. Here's what it looks like - you can see the ~20p of gray space at the top there, headers and footers of about 10p each for a section with 0 rows. (source: hanchorllc.com) Here's my pseudo code: ``` - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { if ([section hasRow]) { return 10.0f; } else { return 0.0f; } } - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { if ([section hasRow]) { return 10.0f; } else { return 0.0f; } } ``` I have verified that these methods are being called and that the proper execution path is taking place. One wrinkle - this view controller is using a XIB and that UITableView has the section header and footer values set at 10.0 (default), though I thought that was overriden by the delegate method, if implemented. This is an app targeting 3.0. What am I doing wrong?