简体   繁体   中英

Getting “Unable to simultaneously satisfy constraints” after updating constraint in iOS 7

I've got a UITableViewController, with a custom view, with some subviews and controls inside, in the header of the table. Each one of these subviews are a custom subview (use a custom subview to draw corner radius with IBInspectable) and each have constraints for top, bottom, leading and trailing space (all set to 8) as well as for height (set to 60, 80 or 100, depending of each subview).

One of these subviews constraints can be modified programmatically in run time depending of user interaction. To do that, I create this two methods:

- (void)showSearchTypeTermField:(BOOL)animated
{
    self.searchTypeHeightConstraint.identifier = @"Height 100";

    [self.searchTypeHeightConstraint setConstant:100.0];

    if (animated) {
        [self.tableView.tableHeaderView layoutIfNeeded];
        [UIView animateWithDuration:0.3 animations:^{
            [self.tableView.tableHeaderView layoutIfNeeded];
        }];
    } else {
        [self.tableView.tableHeaderView layoutIfNeeded];
    }

    self.searchTypeTermField.hidden = NO;
    self.searchTypeTermField.text = @"";

    [self.tableView.tableHeaderView systemLayoutSizeFittingSize:UILayoutFittingExpandedSize];
}

- (void)hideSearchTypeTermField:(BOOL)animated
{
    self.searchTypeHeightConstraint.identifier = @"Height 60";

    [self.tableView.tableHeaderView setAutoresizingMask:UIViewAutoresizingFlexibleHeight];

    [self.searchTypeHeightConstraint setConstant:60.0];

    if (animated) {
        [self.tableView.tableHeaderView layoutIfNeeded];
        [UIView animateWithDuration:0.3 animations:^{
            [self.tableView.tableHeaderView layoutIfNeeded];
        }];
    } else {
        [self.tableView.tableHeaderView layoutIfNeeded];
    }

    self.searchTypeTermField.hidden = YES;

    [self.tableView.tableHeaderView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
}

Because all of these subviews are in the table header view, every time I change the constraint, header should expand or compress depending of the case, thats why I use self.tableView.tableHeaderView systemLayoutSizeFittingSize .

The problem is I'm getting this error, when I call [self hideSearchTypeTermField:NO] the first time on viewdidLoad despite that visually everything seems fine:

Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x7bf504e0 V:[SeachFormBackgroundView:0x7bea3ab0(60)]>",
    "<NSLayoutConstraint:0x7bf51760 V:[SeachFormBackgroundView:0x7bf50690(60)]>",
    "<NSLayoutConstraint:0x7bf53390 'Height 60' V:[SeachFormBackgroundView:0x7bf518e0(60)]>",
    "<NSLayoutConstraint:0x7bf53ec0 V:[SeachFormBackgroundView:0x7bf535a0(80)]>",
    "<NSLayoutConstraint:0x7bf54a80 V:[SeachFormBackgroundView:0x7bf54180(80)]>",
    "<NSLayoutConstraint:0x7bf54eb0 V:|-(8)-[SeachFormBackgroundView:0x7bea3ab0]   (Names: '|':UIView:0x7bea3a10 )>",
    "<NSLayoutConstraint:0x7bf54f40 V:[SeachFormBackgroundView:0x7bea3ab0]-(8)-[SeachFormBackgroundView:0x7bf50690]>",
    "<NSLayoutConstraint:0x7bf54f70 V:[SeachFormBackgroundView:0x7bf50690]-(8)-[SeachFormBackgroundView:0x7bf518e0]>",
    "<NSLayoutConstraint:0x7bf55090 V:[SeachFormBackgroundView:0x7bf518e0]-(8)-[SeachFormBackgroundView:0x7bf535a0]>",
    "<NSLayoutConstraint:0x7bf550f0 V:[SeachFormBackgroundView:0x7bf54180]-(8)-|   (Names: '|':UIView:0x7bea3a10 )>",
    "<NSLayoutConstraint:0x7bf55180 V:[SeachFormBackgroundView:0x7bf535a0]-(8)-[SeachFormBackgroundView:0x7bf54180]>",
    "<NSAutoresizingMaskLayoutConstraint:0x7c149fc0 h=--& v=--& V:[UIView:0x7bea3a10(428)]>"
)

I'm really lost with this issue. What I'm doing wrong?

Thanks.

If you try adding the heights for the SeachFormBackgroundView instances (60 + 60 + 60 + 80 + 80 + 8 * 6 = 388 and their separators you'll see that they aren't equal to the parent UIView height (428). That's why you get this message.

You have to either adjust the constraints so that they add up to the parent view height, or resize the parent so that it's size matches the child constraints.

You don't need all of the constraints you have right now. Since you're setting a specific height to all of the subviews and spacing constraints, you only need to anchor them to the top or to the bottom of the superview.

Edit:

You don't need both of these constraints: V:|-(8)-[SeachFormBackgroundView:0x7bea3ab0] and V:[SeachFormBackgroundView:0x7bf54180]-(8)-| . The first one anchors your subviews to the top of the superview, and the scond one anchors them to the bottom of your superview. Remove one of them (I'd expect the bottom one) and the views will fall in place without throwing any AutoLayout exceptions.

When you set the header view the table view reads its size and sets a constraint for that height. Updating the constraints on the header view itself don't cause a reevaluation of that height. You should remove the header view, update its constraints, lay it out and then add the header view again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM