简单自定义 UITableViewCell 的自动布局错误

Posted

技术标签:

【中文标题】简单自定义 UITableViewCell 的自动布局错误【英文标题】:Autolayout Error With Simple Custom UITableViewCell 【发布时间】:2016-09-21 04:58:12 【问题描述】:

这是我的布局:

问题是关于第二个自定义单元格。我有一个 UIImageView 和一个 UILabel。我想让一个图像在单元格的左侧对齐,并且标签填充了另一个可用空间。

我已经录制了一个 GIF 动画来展示这个过程

结果正常。但后来我想为我的自定义单元格选择 Detail Accessory 选项。

之后我得到了这个:

2016-09-21 11:23:57.976 ODFileManager2[4861:70193] 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:0x7fe62addd190 H:[fileIcon(43)]   (Names: fileIcon:0x7fe62addcfc0 )>",
    "<NSLayoutConstraint:0x7fe62addf1b0 fileIcon.leading == UITableViewCellContentView:0x7fe62addc2c0.leadingMargin   (Names: fileIcon:0x7fe62addcfc0 )>",
    "<NSLayoutConstraint:0x7fe62addf340 H:[fileIcon]-(0)-[UILabel:0x7fe62addc7d0'Label']   (Names: fileIcon:0x7fe62addcfc0 )>",
    "<NSLayoutConstraint:0x7fe62addf390 UITableViewCellContentView:0x7fe62addc2c0.trailingMargin == UILabel:0x7fe62addc7d0'Label'.trailing>",
    "<NSLayoutConstraint:0x7fe62ade5e20 'fittingSizeHTarget' H:[UITableViewCellContentView:0x7fe62addc2c0(48)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7fe62addd190 H:[fileIcon(43)]   (Names: fileIcon:0x7fe62addcfc0 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

虽然一切看起来都还不错。

【问题讨论】:

你有没有尝试在将单元格的附件放在那里后添加约束? 我同意@Tj3n,但这个警告背后一定有一些解释。 你是动态增加单元格的高度吗? 您可能添加了一个您可能不需要的约束。这意味着,删除约束不会影响您的视图,并且会满足所有设备。 @Tj3n,是的,没有区别。 【参考方案1】:

高度有问题,你设置为 43,但单元格高度为 48。

解决这个问题的方法是:

    移除约束:fileIcon 的底部和顶部约束。 添加约束:在容器中垂直居中

【讨论】:

在这种情况下存在歧义:图像可以垂直居中并且具有父容器的许多不同高度的前导填充。所以单元格的高度等于标签高度。这是错的。我得到的 fileIcon 大于单元格的高度。单元格的高度必须取决于图像的顶部和底部边缘。并且标签必须填满剩余的空间。 你的意思是说单元格的高度会随着图片的大小而增加。【参考方案2】:

刚刚检查了您的 gif,您将 fileIcon 的顶部和底部固定到单元格的顶部和底部,然后将 fileIcon 的高度限制设置为 43,但根据警告消息,单元格的高度为 48 .这就是自动布局无法满足约束的原因。

【讨论】:

我不知道为什么单元格的高度是 48。我希望单元格根据内在大小动态改变它的高度。实际上在 IB 行高是 87,但在运行时它没有影响。 移除fileIcon的顶部和底部约束,改为在单元格中垂直居中对齐。然后用适当的填充空间将Label 的顶部和底部固定到单元格的顶部和底部。之后,您需要将 tableView 的estimatedRowHeight 设置为一些合理的值。最后在tableView:heightForRowAtIndexPath:中返回UITableViewAutomaticDimension 在这种情况下存在歧义:图像可以垂直居中并且具有父容器的许多不同高度的前导填充。我得到的 fileIcon 大于单元格的高度。单元格的高度必须取决于图像的顶部和底部边缘。并且标签必须填满剩余的空间。 UITableViewAutomaticDimension 和estimatedRowHeight 已设置。 那么单元格的高度是静态的,因为fileIcon的高度是静态的【参考方案3】:

首先,您应该在设置/更改任何约束后更新约束的框架,但您还没有按照您提供的 GIF 所示那样做。

要回答您的问题,您在这里做错的是您设置了不应该做的定点约束。按照以下步骤,您将摆脱所有警告,

    为 imageView 设置行距、垂直居中、固定高度和固定宽度约束。

    将 Labels Leading Space 约束设置为 imageView,并将 Top Space、Trailing Space 和 Bottom Space 设置为 SuperView,标准间距不应该是固定点。

因此,这样您的图像将固定大小,并且您的标签可以根据文本大小增加高度和宽度。

根据需要执行此操作后(如果约束以橙色显示)更新帧。

希望这能帮助你理解自动布局的规则..

祝你好运……

【讨论】:

以上是关于简单自定义 UITableViewCell 的自动布局错误的主要内容,如果未能解决你的问题,请参考以下文章

使用自动布局在自定义 UITableViewCell 上分页 UIScrollView

如何使用 xib 文件自动布局宽度自定义 UITableViewCell

在自定义 UITableViewCell 中忽略自动布局

自动调整 UITableViewCell:更改自定义单元格内视图的高度

具有自动布局的自定义 UITableViewCell 会导致警告

自定义 UITableViewCell 中标签的自动布局优先级