选择时调整单元格大小时出现 NSAutoResizingMaskLayoutConstraint 错误

Posted

技术标签:

【中文标题】选择时调整单元格大小时出现 NSAutoResizingMaskLayoutConstraint 错误【英文标题】:NSAutoResizingMaskLayoutConstraint error when resizing cell upon selection 【发布时间】:2014-09-14 05:22:20 【问题描述】:

我正在实现一个自定义 UITableView,当用户点击该单元格时,它将垂直扩展单个单元格以显示详细信息。

我在 didSelectRowAtIndexPath 处理程序中向 UITableViewCell 调用 addConstraint 时遇到问题:

Unable to simultaneously satisfy constraints.
...
If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0xa0c9cc0 V:[UITableView:0xc339c00]-(0)-|   (Names: '|':UITableViewCellContentView:0xa0c8910 )>",
    "<NSAutoresizingMaskLayoutConstraint:0xa0b8600 h=--& v=--& V:[UITableViewCellContentView:0xa0c8910(25)]>",
    "<NSLayoutConstraint:0xa0caad0 V:|-(42)-[UITableView:0xc339c00]   (Names: '|':UITableViewCellContentView:0xa0c8910 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0xa0c9cc0 V:[UITableView:0xc339c00]-(0)-|   (Names: '|':UITableViewCellContentView:0xa0c8910 )>  

这里有一些关于我的实现的更多细节:

    当用户选择一个单元格时,didSelectRowAtIndexPath 在我的子类 UITableView 中被调用,我在其中更新了一个名为 selectedRowIndex 的成员。 同样在 didSelectRowAtIndexPath 中,我在一个单元格上调用 addConstraint(我通过 [tableView cellForRowAtIndexPath:indexPath] 检索它)。这是一个垂直约束:“V:|-(42)-[embeddedTableView]”,它确保在单元格的详细视图中另一个嵌入表格上方有空间。 didSelectRowAtIndexPath 完成后,将调用 heightForRowAtIndex。我的 heightForRowAtIndex 实现将检查 selectedRowIndex 值并为所选行返回更大的高度。

在第 2 步,出现上述“无法同时满足约束”错误。我相信这是因为在 heightForRowAtIndex 之前调用了 didSelectRowAtIndexPath。我的预感是 translatesAutoresizingMaskIntoConstraints 设置(在我的实现中为“是”)正在创建基于单元格高度的运行时值的新约束,该值在运行 didSelectRowAtIndexPath 代码后更新。

有解决此问题的推荐方法吗?或者是否有另一种方法来执行单元格扩展,仍然允许我为单元格的内容设置必要的单元格约束?

【问题讨论】:

展开单元格时要添加什么约束?您需要描述在扩展之前您有哪些限制,以及您想要改变什么。 添加了要添加到第 2 步的约束:“V:|-(42)-[embeddedTableView]”。 另外值得注意的是输出的冲突中列出的 NSAutoresizingMaskLayoutConstraint (UITableViewCellContentView(25))。 25 的值似乎来自原始单元格高度(扩展之前) - 根据先前调用 heightForRowAtIndexPath 计算/返回。 如果不了解您的单元格中的所有限制,很难判断发生了什么。另外,您说 translatesAutoresizingMaskIntoConstraints 设置为 YES。对于什么视图设置为 YES?您是否在代码中向您的单元格添加视图? translatesAutoresizingMaskIntoConstraints 对于我的所有视图都设置为 YES(默认)。 【参考方案1】:

想通了。我的部分问题与这里的解决方案有关:How is it possible that UITableViewCellContentView height is different from heightForRowAtIndexPath:

我发现我需要在单元格的子类 awakeFromNib 中添加 [self.contentView setAutoresizingMask:UIViewAutoresizingFlexibleHeight] 以允许调整单元格的高度。

不过,这还不是全部。在做了一些阅读之后,我找到了与在调用heightForRowAtIndex 之前调用addConstraint 相关的其他问题的答案。我的怀疑是正确的,在didSelectRowAtIndexPath 中调用addConstraint 是有问题的。

根据UIView Class Reference,添加约束的正确方法是我在didSelectRowAtIndexPath 中调用- (void)setNeedsUpdateConstraints。这会导致调用updateConstraints,这是我必须为自定义约束更新实现的函数。

【讨论】:

以上是关于选择时调整单元格大小时出现 NSAutoResizingMaskLayoutConstraint 错误的主要内容,如果未能解决你的问题,请参考以下文章

当边界 UICollectionView 更改时调整单元格大小

单击Swift 4中的自定义按钮时调整单元格大小

使用自动布局在屏幕更改时调整自定义单元格中的 UIButton 字体

嵌套集合视图单元格未在方向更改时调整大小

自定义 UITableViewCell 中的 UIImageView 在单击时调整大小

在运行时调整 UITableView 的单元格