首页 > 解决方案 > 当表格视图单元格中的条件更改时,自动布局约束中断

问题描述

在我的 tableView 单元中,我有一个来自 API 的字符串数组,用于根据数组元素的数量确定堆栈视图的高度。数组可以有 3、4 或 X 个元素。

var pollDataInPollCell: PollModel? {
        didSet{
            if let pollOptions = pollDataInPollCell?.poll_detail{
                // pollOptions = ["A", "B"] or ["A", "XS", "XSMAX"]

           optionBtnStackView.heightAnchor.constraint(equalToConstant: CGFloat(30 * pollOptions.count).isActive = true
}
var optionBtnStackView: UIStackView = {
   let sv = UIStackView()
    sv.axis = .vertical
    sv.distribution = .fillEqually
    return sv
}()

启动时一切正常。每行的 stackView 高度看起来很完美,并且没有破坏约束。但是,如果我上下滚动 tableView,我的 stackView 高度不再相同,我相信这是由于 tableView dequeueReusableCell。我的问题是是否可以在 didSet 中重置我的 stackView 高度,以便它可以呈现新的高度。我在 didSet 中试过这个

optionBtnStackView.heightAnchor.constraint(equalToConstant: 0).isActive = true
optionBtnStackView.heightAnchor.constraint(equalToConstant: CGFloat(30 * pollOptions.count).isActive = true

或者

optionBtnStackView.heightAnchor.constraint(equalToConstant: CGFloat(30 * pollOptions.count).isActive = false
optionBtnStackView.heightAnchor.constraint(equalToConstant: CGFloat(30 * pollOptions.count).isActive = true

但两者都不能解决我的问题。有什么建议么?太感谢了。

标签: iosswiftuitableviewconstraints

解决方案


我会假设您只是在旧约束中添加新约束,然后它们就会发生碰撞。

这一行:

optionBtnStackView.heightAnchor.constraint(equalToConstant: CGFloat(30 * pollOptions.count)).isActive = true

创建并激活一个的约束。如果您再次使用不同的数据调用同一行,则会添加一个具有不同高度的新约束,然后它们会发生碰撞。

解决方案应该非常简单。首先创建一个属性并保留对单个约束的引用。然后,在设置数据时,只更新常量,不要创建新的约束。

例如,类似:

fileprivate var stackHeightConstraint: NSLayoutConstraint?

var pollDataInPollCell: PollModel? {
    didSet {
        if let pollOptions = pollDataInPollCell?.poll_detail {
            // lazily initialized heightConstraint:
            if stackHeightConstraint == nil {
                // this creates the constraint and keeps a reference to it
                stackHeightConstraint = optionBtnStackView.heightAnchor.constraint(equalToConstant: CGFloat(30 * pollOptions.count))
                // and we can activate it properly
                stackHeightConstraint?.isActive = true
            } else {
                // here the stackHeightConstraint is initialized, so just set the constant
                stackHeightConstraint?.constant = CGFloat(30 * pollOptions.count)
            }
        }
    }
}

推荐阅读