UITableView dequeueReusableCell 重复约束

Posted

技术标签:

【中文标题】UITableView dequeueReusableCell 重复约束【英文标题】:UITableView dequeueReusableCell duplicates constraints 【发布时间】:2019-06-29 22:26:45 【问题描述】:

使用 swift,我有一个 UITableView 和自定义 UITableViewCells。每个单元格初始化后,我调用一个方法(layoutViews())来应用适当的约束(NSLayoutConstraint.activate([...])。一个约束,即标签前导锚点,是基于行的动态约束,并导致父记录和子记录之间出现某种缩进。

例子:

Parent
    Child
Parent
Parent
    Child
        Grandchild
    Child
    Child

当我滚动时,约束会变得混乱并导致同一单元格上出现重复的约束

错误:无法同时满足约束...将尝试通过打破约束来恢复)。

大多数时候没有缩进应该执行。

我已尝试停用先前的约束,删除先前的约束,并从超级视图中删除所有视图。我得到了各种结果,但没有一个是正确的。

我只希望缩进与我在getIndentaion() 函数中提供的CGFloat 值相匹配。

根据要求,这里是相关代码(当然是缩写形式)。

在 UIViewController 中:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomCell
    cell.setIndentation(2)
    cell.layoutViews()
    return cell

在自定义单元中:

func getIndentation() -> CGFloat 
    return 5 + ((indentation ?? 0) * 15)


func layoutViews() 
    NSLayoutConstraint.activate([
        messageLabel.leadingAnchor.constraint(equalTo: messageBackground.leadingAnchor, constant: getIndentation())
    ])

感谢任何帮助。

【问题讨论】:

请出示相关代码;当他的单元被重用时,你不应该添加约束,只有在它被初始化时,例如在awakeFromNib 感谢您的评论,@Paulw11。这就是我遇到的问题。缩进是根据 dequeueReusableCell 语句中未提供的值执行的。如何根据单元格初始化后提供的数值实现动态缩进? 您需要添加一次约束,然后更新其constant,而不是每次布局单元格时添加约束。 谢谢。那行得通。这正是我所需要的。请将其作为答案发布,以便我将其选为最佳回复。 【参考方案1】:

谢谢你,@Paulw11。以下解决方案有效:

在 UIViewController 中:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomCell
    cell.setIndentation(2)
    return cell

在自定义单元中:

var indentationConstraint: NSLayoutConstraint!

func layoutViews() 
    indentationConstraint = messageLabel.leadingAnchor.constraint(equalTo: messageBackground.leadingAnchor, constant: 5)

    NSLayoutConstraint.activate([
        indentationConstraint
        ])
    


func setIndentation(_ indentation: CGFloat) 
    let totalIndentation: CGFloat = 5 + (indentation * 15)
    indentationConstraint.constant = totalIndentation
    messageLabel.layoutIfNeeded()

【讨论】:

以上是关于UITableView dequeueReusableCell 重复约束的主要内容,如果未能解决你的问题,请参考以下文章

将 UITableView 推送到 UITableView

UItableview 单元格的动态高度与 UItableview 单元格内的 UItableview

UITableView

水平 UITableView 中的垂直 UITableView

如何与重叠显示的 UITableView 交互另一个 UITableView

在 UITableView 中的 UINib 中重新加载 UITableView