0

This is my code:

let b = NSLayoutConstraint(item: some, attribute: fromAttribute, relatedBy: NSLayoutRelation.equal, toItem: some2, attribute: toAttribute, multiplier: multiplier, constant: -5)
b.isActive = true
self.layoutIfNeeded()
print(b.constant)
print(some.constraints.first(where: {$0.constant == -5 }))

And this is my print:

-5.0
nil

How can I get that constraint back in code? Why does it print out nil? I want to animate the constraint's constant later on. Thanks.

J. Doe
  • 12,159
  • 9
  • 60
  • 114
  • Make it a class-level variable / property, instead of a local-scoped variable. – DonMag Sep 21 '17 at 20:13
  • @DonMag Would it make a difference you think? You mean variable B class-level variable right? – J. Doe Sep 21 '17 at 20:17
  • How do you now that the constraint is added to `some`? Show us the view hierarchy please. If `some2` is not a subview of `some`, then this cannot work. – Sulthan Sep 21 '17 at 20:22

2 Answers2

1

Let's start with the core question:

How can I get that constraint back in code?

Ideally, you don't. You save it to a variable when you create it, e.g.:

var myConstraint: NSLayoutConstraint?

func x() {
   let b = NSLayoutConstraint(...)
   ...
   myConstraint = b
}

Why does it print out nil?

When setting isActive = true, the constraint is added to the closest common superview. For example, if A is a superview of B and you have a same-width constraint, then the constraint is added to A and it won't be present on B.

The constraint will be added to some only if some2 is a subview of some.

Sulthan
  • 128,090
  • 22
  • 218
  • 270
  • Yes I was just reading your comment and I thought maybe it is added to my superview (some2). Well, that was another hour scratching my head >:( – J. Doe Sep 21 '17 at 20:28
0

Use a class-level variable to hold the constraint you want to modify. If you are using storyboards / Interface Builder, you can also assign a constraint as an IBOutlet.

class ViewController: UIViewController {

    var constraintToAnimate: NSLayoutConstraint?

    override func viewDidLoad() {
        super.viewDidLoad()

        constraintToAnimate = NSLayoutConstraint(item: some, attribute: fromAttribute, relatedBy: NSLayoutRelation.equal, toItem: some2, attribute: toAttribute, multiplier: multiplier, constant: -5)
        constraintToAnimate.isActive = true

    }

    // later, perhaps in a button tap...

    func animateIt() {

        constraintToAnimate?.constant = 100

    }

}
DonMag
  • 69,424
  • 5
  • 50
  • 86