当表视图单元格中的条件发生变化时,自动布局约束会中断

时间:2018-09-19 06:18:12

标签: ios swift uitableview constraints

在tableView单元格中,我有一个来自API的字符串数组,用于根据数组元素的数量确定stackview的高度。该数组可以包含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

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

1 个答案:

答案 0 :(得分:0)

我认为您只是在向旧约束添加新约束,然后它们会发生冲突。

此行:

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)
            }
        }
    }
}