启用+禁用自动布局约束

我有一个简单的(我认为)的问题:我有一个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]> 。 有谁知道为什么会出现这个错误?

通过调用self.view.addConstraint(...)来添加约束来消除错误,但仍然不会将图像视图返回到应该在的位置。

我注意到,我甚至不必删除或停用约束条件就可以设置的imageView框架没有问题,只要我不调用setTranslatesAutoresizingMaskIntoConstraints(true)

我已经看到这个问题,但答案似乎不必要的复杂,可能已经过时,甚至不适用。

我也看到了这个问题,但这不包括限制可以重新启用 – 只有如何可以禁用。

试图设置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)

而且,根据我的testing和JoachimBøggild 在这里的回答,似乎当约束的active属性设置为false时,该约束变为零,因此不能被重新激活。

将约束添加到数组并激活/停用它们:

有趣的是,这会导致与设置active属性几乎完全相同的问题。 将所有约束放在数组array ,然后调用NSLayoutConstraint.deactivateConstraints(array)使图像视图消失。 此外,以后用NSLayoutConstraint.activateConstraints(array)重新激活约束没有图像视图返回到它应该在哪里 – 它保持原来的位置。

啊哈!

一旦其active属性设置为false,约束将变为零(因此不能重新激活)。 让他们强有力的参考 (谢谢,迦勒,清理命名)保留它们,使他们可以激活和停用所需的。

如果你看看NSLayoutConstraint的文档,你会发现一个名为Activating and Deactivating Constraints的部分描述了active属性 ,这个部分反过来告诉你:

您可以通过更改此属性来激活或取消激活约束…激活或取消约束调用addConstraint:和removeConstraint:对该约束所pipe理的项目中最接近的共同祖先的视图。 使用此属性而不是直接调用addConstraint:或removeConstraint:。

所以,一旦你有一个strong引用的约束(如你有你的sockets),你可以简单地将其active属性设置为false (或Obj-C中的NO )禁用,或者true (或是) 启用。

将约束连接从故事板的IBOutlet连接到ViewController,并在数组中创build一个Array add All约束。

不使用时禁用这些约束。

在使用中添加约束。

 NSLayoutConstraint *constraint1; NSLayoutConstraint *constraint2; NSLayoutConstraint *constraint3; NSArray *arr = @[constraint1,constraint2,constraint3]; [NSLayoutConstraint deactivateConstraints:arr]; //After deactivate constraint array add what ever frame you want to add //Activate lateroN [NSLayoutConstraint activateConstraints:arr];