I'm getting the following error after a call to insertSections:withRowAnimation:
and endUpdates
. The error concerns autolayout in my custom UITableViewHeaderFooterView
but only when the header is reused by dequeueReusableHeaderFooterViewWithIdentifier:
. First time it works fine with no errors.
Unable to simultaneously satisfy constraints.
...
(
"<NSLayoutConstraint:0x10b77f9f0 V:|-(8)-[UIView:0x10b77d0f0] (Names: '|':WYBDetailHeaderView:0x10b77e620 )>",
"<NSAutoresizingMaskLayoutConstraint:0x10b77cac0 h=--& v=--& V:[WYBDetailHeaderView:0x10b77e620(0)]>",
"<NSLayoutConstraint:0x10b77fa40 V:[UIView:0x10b77d0f0]-(>=4)-| (Names: '|':WYBDetailHeaderView:0x10b77e620 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x10b77fa40 V:[UIView:0x10b77d0f0]-(>=4)-| (Names: '|':WYBDetailHeaderView:0x10b77e620 )>
There is a similar error for the horizontal constraints. The problem is that a NSAutoresizingMaskLayoutConstraint
appears for both width and height set to zero. However, once the animation completes the header layout is correct and looks fine.
I have followed the advice in this related question with no luck: UITableViewHeaderFooterView subclass with auto layout and section reloading won't work well together
Has anyone encountered something similar before?
Is there something I can do to avoid the warning?
This is the implementation in my UITableView
:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
WYBDetailHeaderView *header = [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"WYB"];
[header setupWithTitle:@"Title" subtitle:@"Subtitle"];
return header;
}
And the implementation of WYBDetailHeaderView (it uses a NIB which I register with registerNib:forHeaderFooterViewReuseIdentifier:
):
- (void)setupWithTitle:(NSString *)title subtitle:(NSString *)subtitle
{
// Set labels.
self.titleLabel.text = title.uppercaseString;
self.subtitleLabel.text = subtitle;
// Clear image.
self.headerImageView.image = nil;
self.emptyImage = NO;
// Mark for layout update.
[self setNeedsUpdateConstraints];
[self setNeedsLayout];
}
- (void)prepareForReuse
{
self.prototype = NO;
self.emptyImage = NO;
}
- (void)updateConstraints
{
// See if there is an image.
if (self.emptyImage || self.headerImageView.image) {
self.imageWidthConstraint.constant = 20;
self.imageHeightConstraint.constant = 20;
self.imageTitleSpaceConstraint.constant = 8;
}
else {
self.imageWidthConstraint.constant = 0;
self.imageHeightConstraint.constant = 0;
self.imageTitleSpaceConstraint.constant = 0;
}
[super updateConstraints];
}
- (void)layoutSubviews
{
[super layoutSubviews];
self.titleLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.titleLabel.frame);
self.subtitleLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.subtitleLabel.frame);
[super layoutSubviews];
}