如何在Swift中以编程方式更改布局约束?

15

我有一个集合视图,每个单元格都有一个textView。这是我的textview约束设置

textView.topAnchor.constraint(equalTo: object1.bottomAnchor).isActive = true
textView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true

...和我的textView的宽度和高度。

现在,由于某个if条件,我想将我的textView的topAnchor更改为对象2的bottomAnchor而不是对象1的bottomAnchor。然而,当我输入下面的代码时,我会得到"Will attempt to recover by breaking constraint"错误。

有人知道如何在已经设置好top anchor的情况下更改它的方法吗?

if (aCondition){
textView.topAnchor.constraint(equalTo: object2.bottomAnchor).isActive = true
}else{
  textView.topAnchor.constraint(equalTo: object1.botttomAnchor).isActive = true
}
1个回答

38

您需要停用旧的活动约束条件。目前,您只是向视图添加新的约束条件。因此,我建议您首先创建两个属性来保留对约束条件的引用:

fileprivate var topConstraint1: NSLayoutConstraint?
fileprivate var topConstraint2: NSLayoutConstraint?

当你开始创建UI时,请确保正确初始化它们:

topConstraint1 = textView.topAnchor.constraint(equalTo: object1.bottomAnchor)
topConstraint2 = textView.topAnchor.constraint(equalTo: object2.bottomAnchor)

激活您想要首先激活的那个:

topConstraint1?.isActive = true

然后当你想要改变约束条件时,你首先停用应该停用的那个,然后激活正确的那个:

if aCondition {
    topConstraint1?.isActive = false
    topConstraint2?.isActive = true
} else {
    topConstraint2?.isActive = false
    topConstraint1?.isActive = true
}

顺便提一下:您总是需要先将旧的停用,然后再激活新的,否则当您激活新的时会与旧的冲突,并在控制台中引发警告。

另外,如果您想要一次性激活多个约束,请使用 NSLayoutConstraint.activate(_:) - 根据文档,这样做更有效:

通常,使用此方法比单独激活每个约束更有效。

所以,例如,可以使用以下方式代替:

someConstraint1.isActive = true
someConstraint2.isActive = true

请使用 "rather":

NSLayoutConstraint.activate([someConstraint1, someConstraint2])

同样适用于取消约束和NSLayoutConstraint.deactivate(_:)


嗨,如果我通过编程方式添加视图并设置约束,应该如何操作? - famfamfam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接