我有一个简单的(我认为)问题:我有一个UIImageView
,我在故事板中设置了多个约束。
有时,我需要禁用约束,并手动设置其frame
,但稍后,我将要重新启用这些约束并让视图返回到原来的位置。约束。
我以为我可以这样做:
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var constraint: NSLayoutConstraint!
func example() {
//to set its location and size manually
imageView.removeConstraint(constraint)
imageView.frame = CGRectMake(...)
//to cause it to return to its original position
imageView.addConstraint(constraint)
}
然而,有了这个,我收到错误2015-08-26 01:14:55.417 Constraints[18472:923024] The view hierarchy is not prepared for the constraint: <NSLayoutConstraint:0x7fbb72815f90 V:[_UILayoutGuide:0x7fbb72814c20]-(100)-[UIImageView:0x7fbb72814540]>
。有谁知道为什么会出现这个错误?
通过调用view
将约束添加到self.view.addConstraint(...)
可以消除错误,但仍然无法将图像视图恢复到原来的位置。
我注意到我甚至不必删除或停用约束,以便能够毫无问题地设置imageView
的框架,只要我不调用setTranslatesAutoresizingMaskIntoConstraints(true)
。
我已经看过this问题了,但答案似乎不必要地复杂,可能过时,甚至不适用。
我也看到了this个问题,但这不包括可以重新启用的限制 - 只能禁用它们。
尝试设置active
属性:
self.top.active = false
self.right.active = false
self.bottom.active = false
self.left.active = false
imageView.frame = CGRectMake(100, 100, 100, 100)
这实际上只会导致imageView
不再可见。 (但是,如果我没有将所有约束'active
属性设置为false,则imageView
会移动到正确的位置。
但真正的问题是,当我尝试将图像视图返回到原来的位置时,通过将所有约束'active
属性设置为true,没有任何反应 - imageView保持原样(在这种情况下由imageView.frame = CGRectMake(100, 100, 100, 100)
指定。
此外,根据我的测试和JoachimBøggild的回答here,似乎当约束的active
属性设置为false时,该约束变为零,因此无法重新激活。
向阵列添加约束并激活/停用它们:
有趣的是,这会导致与设置active
属性几乎完全相同的问题。将所有约束放在数组array
中,然后调用NSLayoutConstraint.deactivateConstraints(array)
会使图像视图消失。此外,稍后使用NSLayoutConstraint.activateConstraints(array)
重新激活约束时,图像视图不会返回到它应该保持原样的位置。
答案 0 :(得分:64)
啊哈!
一旦active
属性设置为false,约束就会变为零(因此无法重新激活)。使它们成为强引用(感谢Caleb,为了清除命名法)保留它们,以便可以根据需要激活和停用它们。
答案 1 :(得分:31)
如果您查看NSLayoutConstraint
的文档,您会找到一个名为Activating and Deactivating Constraints的部分来描述active
property,后者会告诉您:
您可以通过更改此属性来激活或取消激活约束...激活或取消激活约束会调用addConstraint:和removeConstraint:在视图上,该视图是此约束管理的项目的最近共同祖先。使用此属性而不是直接调用addConstraint:或removeConstraint:
因此,一旦您获得了 strong
对相关约束的引用(例如您的插座),您只需设置它即可。 active
属性false
(或Obj-C中的NO
)禁用,或true
(或YES
)启用。