2

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];
}
Community
  • 1
  • 1
AndrewC
  • 401
  • 4
  • 19
  • Show me your implementation of tableView:viewForHeaderInSection: method and prepareForReuse: – bilobatum Apr 23 '14 at 23:26
  • Thanks @bilobatum I have edited the post with the implementation of both functions you requested. – AndrewC Apr 24 '14 at 10:13
  • Actually I wonder if my problem is related to something similar in this question: http://stackoverflow.com/questions/17581550/uitableviewheaderfooterview-subclass-with-auto-layout-and-section-reloading-won. Sadly none of the suggestions there have helped in my case. – AndrewC Apr 24 '14 at 10:24
  • With some more testing I have discovered that the error is definitely caused by the call to `insertSections:withRowAnimation:` and then `endUpdates`. And definitely only when the header is reused. There are no visible problems with the layout during animation, and when the animation is complete the layout is correct. I will update my question accordingly. – AndrewC Apr 24 '14 at 15:55
  • I have similar problems with a custom UIView used as UITableView section header, but only throws the Exception when called - tableView:reloadSection: (which I use to "collapse" a section of tableView cells) – race_carr Jun 08 '14 at 19:39
  • I've just run in to this. I'm only finding it with testing on iOS 8.1 – my testing until now had been 8.3, where I don't get the problem. Seems like no answers though? – Benjohn Jul 20 '15 at 12:52

1 Answers1

0

I just had a similar error and making use of estimatedHeightForRowAtIndexPath caused it.

Luke Rhodes
  • 293
  • 3
  • 13