Jeff Nouwen Jeff Nouwen - 3 months ago 35
iOS Question

-systemLayoutSizeFittingSize: returning incorrect height for tableHeaderView under iOS 8

There are numerous threads about correctly sizing a tableHeaderView with auto-layout (one such thread) but they tend to pre-date iOS 8.

I have a situation with numerous table views, all with headers, that size correctly under iOS 7 but incorrectly under iOS 8 using the code that most of the aforementioned threads champion. In the controllers for the tables, I have the following method:

- (void)rejiggerTableHeaderView
{
self.tableView.tableHeaderView = nil;

UIView *header = self.headerView;

[header setNeedsLayout];
[header layoutIfNeeded];

CGFloat height = [header systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

CGRect headerFrame = header.frame;
headerFrame.size.height = height;

header.frame = headerFrame;

self.tableView.tableHeaderView = header;
}


With a multi-line label under iOS 7, this correctly sizes the table view's header like so:



But the same code run under iOS 8 produces the following:



What's the trick to getting -systemLayoutSizeFittingSize: to return the correct size under iOS 8? Here's a sample project that demonstrates the issue.

Answer

Changing your headerview function to the following works for me:

- (void)rejiggerTableHeaderView
{
    self.tableView.tableHeaderView = nil;

    UIView *header = self.headerView;
    CGRect frame = header.frame;
    frame.size.width = self.tableView.frame.size.width;
    header.frame = frame;

    [header setNeedsLayout];
    [header layoutIfNeeded];

    CGFloat height = [header systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

    CGRect headerFrame = header.frame;
    headerFrame.size.height = height;

    header.frame = headerFrame;

    self.tableView.tableHeaderView = header;
}
Comments