获得"无法同时满足约束条件#34;在iOS 7中更新约束后

时间:2015-08-28 08:13:33

标签: ios objective-c uitableview autolayout

我有一个UITableViewController,带有一个自定义视图,里面有一些子视图和控件,在表的标题中。这些子视图中的每一个都是自定义子视图(使用自定义子视图以IBInspectable绘制角半径),每个子视图都有顶部,底部,前导和尾随空间(全部设置为8)以及高度(设置为60, 80或100,取决于每个子视图。)

可以根据用户交互在运行时以编程方式修改其中一个子视图约束。为此,我创建了这两种方法:

- (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];
}

由于所有这些子视图都在表头视图中,因此每次更改约束时,标头都应根据具体情况进行扩展或压缩,这就是我使用self.tableView.tableHeaderView systemLayoutSizeFittingSize的原因。

问题是,当我第一次在[self hideSearchTypeTermField:NO]上致电viewdidLoad时,我发现此错误,尽管视觉上一切似乎都很好:

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)]>"
)

我真的迷失了这个问题。我做错了什么?

感谢。

2 个答案:

答案 0 :(得分:1)

如果您尝试为SeachFormBackgroundView个实例添加高度(60 + 60 + 60 + 80 + 80 + 8 * 6 = 388及其分隔符,您会发现它们并不相等到父UIView高度(428)。这就是你收到这条消息的原因。

您必须调整约束以使它们相加到父视图高度,或者调整父级的大小以使其大小与子约束匹配。

您现在不需要所有限制。由于您要为所有子视图和间距约束设置特定高度,因此您只需将它们锚定到超级视图的顶部或底部。

编辑:

您不需要这两种约束:V:|-(8)-[SeachFormBackgroundView:0x7bea3ab0]V:[SeachFormBackgroundView:0x7bf54180]-(8)-|。第一个将您的子视图锚定到超级视图的顶部,第二个将它们锚定到超级视图的底部。删除其中一个(我希望底部的一个),视图将落在原位而不会抛出任何AutoLayout异常。

答案 1 :(得分:0)

设置标题视图时,表视图会读取其大小并为该高度设置约束。更新标题视图本身的约束不会导致重新评估该高度。您应该删除标题视图,更新其约束,将其布局,然后再次添加标题视图。