sulabh
sulabh

Reputation: 249

Get NSLayoutConstraint Identifier is not working for topAnchor

I want to change TopAnchor Constraint of some View at runtime .

Constraint Created:

 self.buttonHStack.topAnchor.constraint(equalTo: cellHStack.bottomAnchor , constant: 20).activate(withIdentifier: "topAnchor")

Extension

extension UIView {
    func getConstraint(withIndentifier indentifier: String) -> NSLayoutConstraint? {
        return self.constraints.filter { $0.identifier == indentifier }.first
    }
}

extension NSLayoutConstraint {
    func activate(withIdentifier identifier: String) {
        self.identifier = identifier
        self.isActive = true
    }
}

Usage

self.myStackView.topAnchor.constraint(equalTo: someView.bottomAnchor , constant: 20).activate(withIdentifier: "topAnchor") 

But when I try to get its reference:

    if let filteredConstraint = self.myStackView.getConstraint(withIndentifier: "topAnchor") {

//Edit here
    } 

Its not going into the block

Upvotes: 0

Views: 247

Answers (1)

matt
matt

Reputation: 535606

The problem is that you are calling getConstraint on the wrong view. When you activate a constraint between myStackView and some other view:

self.myStackView.topAnchor.constraint(
    equalTo: someView.bottomAnchor , constant: 20).activate(withIdentifier: "topAnchor") 

...that constraint belongs to the common superview of myStackView and someView. So when you say

self.myStackView.getConstraint(withIndentifier: "topAnchor")

... it isn't there. You're looking in the wrong view for your constraint.

But your getConstraint method (evidently taken from here) is a good idea, so let's rewrite it more correctly (and more elegantly) so that we walk up the view hierarchy looking for the constraint:

extension UIView {
    func constraint(withIdentifier id: String) -> NSLayoutConstraint? {
        return self.constraints.first { $0.identifier == id } ??
               self.superview?.constraint(withIdentifier: id)
    }
}

Now (changing the name of course) your method call will work even when you call it on myStackView.

Upvotes: 1

Related Questions