简体   繁体   English

在iOS 7中更新约束后得到“无法同时满足约束”

[英]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. 我在表的标题中有一个UITableViewController,带有一个自定义视图,其中包含一些子视图和控件。 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). 这些子视图中的每个子视图都是一个自定义子视图(使用自定义子视图通过IBInspectable绘制拐角半径),每个子视图都对顶部,底部,前导和尾随空间(均设置为8)以及高度(设置为60, 80或100,具体取决于每个子视图)。

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 . 因为所有这些子视图都在表标题视图中,所以每次更改约束时,标题都应根据情况扩展或压缩,这就是为什么我使用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: 问题是,当我第一次在viewdidLoad上调用[self hideSearchTypeTermField:NO]时,尽管在视觉上看起来一切正常,但我遇到了此错误:

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. 如果尝试为SeachFormBackgroundView实例(60 + 60 + 60 + 80 + 80 + 8 * 6 = 388)及其分隔符添加高度,您会发现它们不等于父UIView高度(428)。这就是原因您会收到此消息。

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)-| 您不需要这两个约束: V:|-(8)-[SeachFormBackgroundView:0x7bea3ab0]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. 删除其中之一(我希望是最下面的一个),视图将就位,而不会引发任何AutoLayout异常。

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. 您应该删除标题视图,更新其约束,进行布局,然后再次添加标题视图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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