Randoms Randoms - 1 year ago 165
iOS Question

Enable + Disable Auto-Layout Constraints

I have a simple (I think) problem: I have a

, which I have set multiple constraints for in the storyboard.

At times, I'll need to disable the constraints, and set its
manually, but later, I'll want to re-enable those constraints and have the view return to where it was as decided by the constraints.

I thought I could do this with something like:

@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var constraint: NSLayoutConstraint!

func example() {

//to set its location and size manually
imageView.frame = CGRectMake(...)

//to cause it to return to its original position


With this, however, I get the error
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]>
. Does anyone know why this error occurs?

Adding the constraints instead to
by calling
gets rid of the error, but still doesn't bring the image view back to where it should be.

I notice I don't even have to remove nor deactivate constraints to be able to set the frame of the
without problem, so long as I don't call

I've already seen this question, but the answer seems unnecessarily complicated, perhaps outdated, and even inapplicable.

I also saw this question, but this doesn't cover constraints can be re-enabled—only how they can be disabled.

Trying to set the

self.top.active = false
self.right.active = false
self.bottom.active = false
self.left.active = false

imageView.frame = CGRectMake(100, 100, 100, 100)

This actually just results in
being no longer visible. (If I don't set all the constraints'
property to false, however,
moves to the proper position.

The real problem, though, is that when I try to have the image view return to where it was, by setting all the constraints'
property to true, nothing happens—the imageView stays where it was (in this case as specified by
imageView.frame = CGRectMake(100, 100, 100, 100)

Also, it seems, according to my testing and Joachim Bøggild's answer here, that when a constraint's
property is set to false, that constraint becomes nil, and thus cannot be re-activated.

Adding constraints to an array and activating/deactivating them:

Interestingly, this causes almost exactly the same issues as setting the
property. Placing all the constraints in an array
, then calling
makes the image view disappear. Also, re-activating the constraints later with
doesn't have the image view return to where it should—it stays where it was.


Constraints become nil (and thus can't be reactivated), once their
property is set to false. Making them strong references (thanks, Caleb, for clearing up the nomenclature) preserves them so they can be activated and deactivated as desired.

Answer Source

If you look at the docs for NSLayoutConstraint you'll find a section called Activating and Deactivating Constraints that describes the active property, which in turn tells you:

You can activate or deactivate a constraint by changing this property...Activating or deactivating the constraint calls addConstraint: and removeConstraint: on the view that is the closest common ancestor of the items managed by this constraint. Use this property instead of calling addConstraint: or removeConstraint: directly.

So, once you've got a reference to the constraint in question (such as you have with your outlet), you can simply set it's active property to false (or NO in Obj-C) to disable, or true (or YES) to enable.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download