分隔符在具有自动行高的 UITableView 中生成约束问题 [重复]

Posted

技术标签:

【中文标题】分隔符在具有自动行高的 UITableView 中生成约束问题 [重复]【英文标题】:Separators generating constraint problem in UITableView with automatic row height [duplicate] 【发布时间】:2020-03-13 08:44:28 【问题描述】:

我正在尝试使用自定义单元格消除我的 UITableView 中出现的约束问题。行的高度设置为自动,并由约束定义。

例如,我有一个单元格只包含一个 UITextField,它的高度设置为 (44.0),并且粘在顶部和底部。

当我的UITableView 上的分隔符被停用时,没有问题。因此,当我激活它们时,我的控制台中会出现以下警告:

[LayoutConstraints] 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. 
(
    "<NSLayoutConstraint:0x28333a670 UITextField:0x103655390.height == 44   (active)>",
    "<NSLayoutConstraint:0x28333a7b0 V:[UITextField:0x103655390]-(0)-|   (active, names: '|':UITableViewCellContentView:0x103654e20 )>",
    "<NSLayoutConstraint:0x28333a990 V:|-(0)-[UITextField:0x103655390]   (active, names: '|':UITableViewCellContentView:0x103654e20 )>",
    "<NSLayoutConstraint:0x28333ba20 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x103654e20.height == 44.3333   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x28333a670 UITextField:0x103655390.height == 44   (active)>

似乎系统添加了UIView-Encapsulated-Layout-Height 约束来设置高度,它包含分隔符的大小(0.33)。它与所需的高度冲突,并覆盖了我的约束。

当我尝试通过更改 UITextField 的高度来更新单元格的高度时,这是一个问题。

有什么办法可以消除那些烦人的警告吗?

编辑

感谢您,我找到了一种方法来消除警告并在运行时获得动画高度变换:

1:设置底部约束优先级≤999,

2:约束改变后,调用

tableView.beginUpdates()
tableView.endUpdates()

这将重新计算行高,UITableView 会自动为更改设置动画。

但是动画有问题……

如果让底部约束优先级为1000,则动画流畅,但每次约束变化时都会出现警告。

例如,如果将底部约束优先级设置为 999,则警告会消失,但单元格的内容会从一个位置跳转到另一个位置……

我将暂时保留警告,并希望 Apple 在未来的版本中解决此问题。

感谢您的回答!

【问题讨论】:

更改上下约束优先级 这能回答你的问题吗? (具体来说,答案是将底部约束的优先级更改为 999)UITableView auto resizing row constraint breaking mysteriously on iPhone 6Plus 这些解决方案删除了​​警告,但它似乎并不好,因为它告诉系统不要听我的约束。如果我更改UITextField 的高度,则单元格不会更改其高度,因为我的约束已被系统计算的约束删除。 我刚刚对其进行了测试(在将底部约束的优先级更改为 999 之后)– 当我更改文本字段的高度约束的值(例如,60)时,它确实会更改单元格的高度,并且不会产生任何警告。 @TylerTheCompiler 很遗憾听到这个消息,我不适合我。当我动态更新约束常量时,不考虑具有最低优先级的边距,行的高度不会改变并且组件在单元格底部溢出(它的底部边距等于-height像素,因为0 常量值优先级低于系统设置的高度) 【参考方案1】:

@blacKeuz 在 UITableViewDataSource 上的 CellForRowAtIndexPath 上尝试如下操作

    let cell = tableView.dequeueReusableCell(withIdentifier: YourCustomTableViewCell.reuseIdentifier, for: indexPath) as! YourCustomTableViewCell

            cell.setNeedsUpdateConstraints()
            cell.updateConstraintsIfNeeded()


            cell.setNeedsLayout()
            cell.layoutIfNeeded()

            return cell

【讨论】:

不,这不会删除警告。 @blacKeuz 实际上,您需要删除文本字段上的静态高度值44。我希望你不会看到警告。 如果我删除它,那么如何获得自动计算的行高?它依靠约束来计算高度的高度(实际上它在没有分隔符的情况下工作)。 @blacKeuz 似乎您也设置了左右两侧的约束,例如左侧、右侧、顶部和底部。你需要设置 UITableView.estimatedRowHeight = 44.0 然后 UItableView.rowHeight = UITableViewAutomaticDimension. @blacKeuz 否则,您可以使用更大的ThanOrEqualToConstraint 设置您的UITextField 高度,如44。试试这个。我希望它会起作用。

以上是关于分隔符在具有自动行高的 UITableView 中生成约束问题 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

iOS UITableView 解决估算行高和指定行高的矛盾

iPhone + UITableView + 行高

在 UITableView 中使用自动布局进行动态单元格布局和可变行高

在 UITableView 中使用自动布局进行动态单元格布局和可变行高

如何在 uilabel 中使用多行并根据 Swift 中的标签高度自动扩展 uitableview 行高?

tableView 未设置自动行高