更新UITableViewCell约束会导致异常

时间:2014-01-17 16:51:08

标签: ios constraints tableview autolayout

我正在使用Xcode 5和iOS 7 SDK。我在故事板中定义了一个UITableViewCell作为原型,我在单元格中使用autolayout作为子视图。当cellForRowAtIndexPath请求单元格时,我用其数据填充单元格:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    ActivityTableViewCell *tableViewCell = [tableView dequeueReusableCellWithIdentifier:@"Activity"];
    Activity *activity = self.activities[(NSUInteger)indexPath.row];

    [tableViewCell configureWithActivity:activity];

    return tableViewCell;
}

此数据可能会导致其中一个子视图的高度发生变化。我通过修改其约束以及其他约束修改来更改子视图的高度:

@implementation ActivityTableViewCell

- (void)updateConstraints
{
    // Update constraints based on the activity
    self.activityDocumentsTableViewHeightLayoutConstraint.constant = ...;
    self.betweenActivityDocumentsTableViewAndNotesLabelLayoutConstraint.constant = ...;
    self.activityNotesTableViewHeightLayoutConstraint.constant = ...;
    self.betweenActivityNotesTableViewAndContentViewLayoutConstraint.constant = ...;

    [super updateConstraints];
}

- (void)configureWithActivity:(Activity *)activity
{
    // Populate subviews using the activity variable

    [self setNeedsUpdateConstraints];
}

@end

我的ActivityTableViewCell类派生自另一个类,它告诉内容视图自动调整大小以适应其动态大小的子视图:

self.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

我的视图控制器预先计算所有这些单元格的高度并将它们存储在一个数组中。这些高度在heightForRowAtIndexPath中提供。

所有这一切都很完美,直到我滚动表格视图:

2014-01-17 10:41:47.435 ... 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:0x13c4a520 UnknownLabel:0x13c4a440.height == 26>",
    "<NSLayoutConstraint:0x13c4ad20 BorderedTableView:0xd46e000.height == 54>",
    "<NSLayoutConstraint:0x13c4b800 UnknownLabel:0x13c4b720.height == 26>",
    "<NSLayoutConstraint:0x13c4be40 BorderedTableView:0xd462600.height == 74>",
    "<NSLayoutConstraint:0x13c4cc60 BorderedTableView:0xd46e000.top == UnknownLabel:0x13c4a440.bottom + 8>",
    "<NSLayoutConstraint:0x13c4ccc0 BorderedTableView:0xd462600.top == UnknownLabel:0x13c4b720.bottom + 8>",
    "<NSLayoutConstraint:0x13c4cd20 UITableViewCellContentView:0x13c49de0.bottom == BorderedTableView:0xd462600.bottom + 8>",
    "<NSLayoutConstraint:0x13c4cd50 UnknownLabel:0x13c4a440.top == UITableViewCellContentView:0x13c49de0.top + 20>",
    "<NSLayoutConstraint:0x13c4cd80 UnknownLabel:0x13c4b720.top == BorderedTableView:0xd46e000.bottom + 55>",
    "<NSAutoresizingMaskLayoutConstraint:0xb2c1bf0 UITableViewCellContentView:0x13c49de0.height == UITableViewCellScrollView:0x13c4d000.height>",
    "<NSAutoresizingMaskLayoutConstraint:0xb2c2460 UITableViewCellScrollView:0x13c4d000.height == ActivityTableViewCell:0x13c49be0.height>",
    "<NSAutoresizingMaskLayoutConstraint:0x13935110 ActivityTableViewCell:0x13c49be0.height == 318>"
)

请注意,所有垂直常量的总和总计318,因此异常。 318来自我预先计算的高度,并且是该单元格的正确高度。但是,该异常中的第四个约束"<NSLayoutConstraint:0x13c4be40 BorderedTableView:0xd462600.height == 74>"不正确(第一次将此单元格出列并配置时, 正确)。这是因为iOS似乎在调用我的单元格的updateConstraints方法之前应用行高,该方法本身将第四个约束更新为正确的值。

我尝试了多种调用updateConstraintssetNeedsLayout等的组合,但都无济于事。在我的约束更新之前,我根本无法弄清楚如何阻止iOS更新自动调整遮罩。好消息是 updateConstraints之后的被调用 - 最终是 - 约束似乎有效;我正确看到了我的单元格,并且所有子视图的大小都显示正确。我只是不喜欢在控制台中看到这些异常,如果可能的话我宁愿消除它们。

1 个答案:

答案 0 :(得分:0)

我发现真的没有干净的解决方案,除了在其中一个垂直约束上将优先级更改为999。这将消除错误消息本身。