5

I've made a constraint in my storyboard and connected to a variable in my view controller. In updateViewConstraints I set the constraint's active property to false.

When I do

self.view.setNeedsUpdateConstraints()
self.view.layoutIfNeeded()

in viewDidLoad, layoutIfNeeded calls updateViewConstraints which sets the constraint to not active, but then somewhere after this it sets the constraint to active and then UIViewAlertForUnsatisfiableConstraints symbolic breakpoint is hit due to conflict with my other constraints. When I check the value of .active further up the stack at this breakpoint it is true.

This only happens in viewDidLoad. Before the view is displayed on the screen updateViewConstraints is called again, and this time setting the constraint to not active sticks and the layout is correct. I still get the conflicting constraints error in the console. Is this a bug?

Edit: Here's the stack trace leading to setting the constraint to active: enter image description here

Nick
  • 3,958
  • 4
  • 32
  • 47
  • 1
    You could create a subclass of `NSLayoutConstraint` and override `active` `set`. On load, you could pull out the specific constraint you're looking for and recreate it as your subclass, then put a breakpoint in to see who is setting `active`. – Ian MacDonald Feb 25 '15 at 16:10

1 Answers1

4

The active property is actually a virtual property that just indicates if the constraint is installed. If you set it true, it installs itself into the nearest common ancestor of the two views. So it was becoming active because in storyboard it was installed in the view. To fix my problem, I simply unticked Installed in storyboard.

Nick
  • 3,958
  • 4
  • 32
  • 47
  • 1
    But when a constraint's `Installed` checked or not cannot be decided ahead of time, to clarify: within `viewDidLoad` is _not_ the correct time to programmatically override the storyboard and set `active`. Apparently its not until the first call to `viewDidLayoutSubviews`, see http://stackoverflow.com/questions/27494542. I had to make myself a `loading` flag and in `viewDidLayoutSubviews` only if flag its set do i call the setup method i was intending to call from `viewDidLoad` (then clear the flag so it doesn't do it again) – Pierre Houston Jul 15 '16 at 21:32
  • And then you manually "install" it by setting it as "active" in code, right? – Kyle Redfearn Oct 26 '16 at 19:12
  • If you set `active` to `true` it will find the closest common parent of both views concerned and add the constraint to that view. You can also manually add the constraint to a view, then `active` will be `true`. – Nick Nov 08 '16 at 15:46