启用+禁用自动布局约束

时间:2015-08-26 05:19:04

标签: swift nslayoutconstraint

我有一个简单的(我认为)问题:我有一个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)重新激活约束时,图像视图不会返回到它应该保持原样的位置。

2 个答案:

答案 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)启用。