3

I created a strong constraint for a UILabel in a .xib file and an outlet for it.

In my code, I set self.constraint.active = NO, but after the application loads, when I open the Debug View Hierarchy, the same constraint is active.

I tried setting it in viewDidLoad, updateViewConstraints and viewDidLayoutSubviews to no avail.

I also created a NSLayoutConstraint subclass, overwrote the setActive: method and put a breakpoint in it, but only my code triggered it.

Iulian Onofrei
  • 9,188
  • 10
  • 67
  • 113
  • what do you mean re-activates it self? what is the constraint about? – giorashc Mar 29 '17 at 13:33
  • @giorashc, Wait a bit, I hit `enter` to add a tag from the popup window and it decided to post the question instead -_- – Iulian Onofrei Mar 29 '17 at 13:33
  • Where in your code are you setting active to `NO`? Also, is your outlet `weak` or `strong`? I believe constraint outlets must be `strong`. – Hodson Mar 29 '17 at 13:34
  • @Hodson, Updated my question. – Iulian Onofrei Mar 29 '17 at 13:36
  • might be obvious but did you connect the constraint to your xib outlet? – giorashc Mar 29 '17 at 13:37
  • @giorashc :))) Yes, otherwise, my breakpoint wouldn't have been triggered. But I did also check if it's `nil` or not. – Iulian Onofrei Mar 29 '17 at 13:37
  • 1
    What happens if you try setting it to `NO` in `viewDidAppear`? – Hodson Mar 29 '17 at 13:38
  • 1
    @Hodson, It works! But it makes no sense. Why is there another layout pass after `viewDidAppear:`? – Iulian Onofrei Mar 29 '17 at 13:41
  • I don't have time right now to dig into the details. You may be able to get it to work by keeping the code in `viewDidLoad` but I think you have to make a call to `setNeedsUpdateConstraints` or `setNeedsLayout` after you change the active state. I can never remember which to call or if you're meant to call both though. – Hodson Mar 29 '17 at 13:53

1 Answers1

2

When playing with constraints I advise to do it as late as possible. Depending on your case, it might be as early as viewDidLoad.

Whatever you end up doing, you can force a refresh with a layoutIfNeeded call.

You could, if I'm not mistaken, disable your constraint and then force an update of constraints / layout ( updateConstraints setNeedsLayout) and then call layoutIfNeeded. But I think you only need to modify your constraint and doing so will automatically set your view to relayout itself whenever it has the time OR when you call layoutIfNeeded.

Either way, try with just these two lines, otherwise, add the ones I put between parenthesis.

I'm not gonna lie, sometimes constraints are part iOS, part skill, part black magic.

Iulian Onofrei
  • 9,188
  • 10
  • 67
  • 113
Gil Sand
  • 5,802
  • 5
  • 36
  • 78