Edit:
I have found that a much simpler way to avoid the gap between the last section and the table footer is to implement heightForFooterInSection and return a very small value that is not 0. This will result in nothing being visible.
For some reason, returning 0 doesn't suppress the rendering of section footers in a grouped-style table view, and it will try to render a 1-point footer. There is other discussion on StackOverflow about this.
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
return CGFLOAT_MIN;
}
I was able to accomplish this in what feels like a slightly hacky way, but it seems to work fine.
My hack is simply to place the actual footer view you want inside of a wrapper view, with a frame position of (0, -1).
Let's say you have a table footer view that you want to use, a class called MyTableFooterView.
In that case you can do something like this:
//This is the view we will actually add as the table footer
//We make it one point shorter since the content will be shifted up
//one point out of its frame
CGRect footerFrame = CGRectMake(0, 0, self.tableView.width, myFooterHeight-1);
UIView* tableFooterWrapper = [[UIView alloc] initWithFrame:footerFrame];
//This is the view that we are trying to use as a table footer.
//We place it 1 point up inside the wrapper so it overlaps that pesky 1-point separator.
CGRect contentFrame = CGRectMake(0, -1, self.tableView.width, myFooterHeight);
UIView* footerContent = [[MyTableFooterView alloc] initWithFrame:contentFrame];
//Make sure the footer expands width for to other screen sizes
footerContent.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[tableFooterWrapper addSubview:footerContent];
self.tableView.tableFooterView = tableFooterWrapper;
This works reliably for me. It's possible that there's a more idiomatic way, but I haven't come across one yet.