UITableViewHeaderFooterView subclass with auto layout and section reloading won't work well together UITableViewHeaderFooterView subclass with auto layout and section reloading won't work well together ios ios

UITableViewHeaderFooterView subclass with auto layout and section reloading won't work well together


Working Solution as of iOS 9

In your UITableViewHeaderFooterView subclass place the following code.

- (void)setFrame:(CGRect)frame {    if (frame.size.width == 0) {        return;    }        [super setFrame:frame];}

Explanation:

The tableview handles the layout of the header views and it does so by manually manipulating the frames (yes even with autolayout turned on).

If you inspect the width constraints that are on the header/footer views there are two, one contained on the superview (the table view) for the width, and one contained in the header/footer view itself for the width.

The constraint contained on the super view is a NSAutoresizingMaskLayoutConstraint which is the giveaway that the tableview depends on frames to manipulate the headers. Switching the translatesAutoresizingMaskIntoConstraints to NO on the header view affectively breaks its appearance which is another give away.

It appears that under some circumstances these header/footer views will have their frames change to a width of zero, for me it was when rows were inserted and the header views were reused. My guess is that somewhere in the UITableView code a preparation for an animation is made by starting the frame at zero width, even if you are not using an animation.

This solution should work well and should not impact scroll performance.


I ran in to this last week.

The way that I've eliminated the warnings is to change my required constraints to have a priority of 999. This is a work around rather than a fix, but it does get around exceptions being thrown, caught and logged during layout.

Things that didn't work for me.

A suggestion is to set estimatedRowHeight . I tried to set the estimatedSectionHeaderHeight, but this didn't help. Setting an estimatedSectionFooterHeight created empty footers where I didn't want them, which was a bit odd.

I also tried setting translatesAutoresizingMaskIntoConstraints = NO; on the header footer view, and on its content view. Neither got rid of the warning and one lead to the layout breaking completely.


So weird! Thanks for this @josh-bernfield, here is what I wrote for iOS 11.3:

override var frame: CGRect {    get {        return super.frame    }    set {        if newValue.width == 0 { return }        super.frame = newValue    }}