Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get reference to NSLayoutConstraint using Identifier set in storyboard

Tags:

I was setting the constraints of a button using a storyboard. I saw an option, "Identifier" in the constraint's properties.

Screenshot of constraint's properties

I want to make a reference to this constraint, to change its value in code, to move an object.

How can I get a reference to this NSLayoutContraint from this Identifier.

I read the documentation, it was written like this

@interface NSLayoutConstraint (NSIdentifier)
/* For ease in debugging, name a constraint by setting its identifier, which will be printed in the constraint's description.
 Identifiers starting with UI and NS are reserved by the system.
 */
@property (nullable, copy) NSString *identifier NS_AVAILABLE_IOS(7_0);

@end

So I realized that it's for debugging purposes.

What if I want to get it and use it? I saw this link, but no satisfactory answer was given: How to get NSLayoutConstraint's identifier by Its pointer?

like image 260
Sam Shaikh Avatar asked Oct 09 '15 12:10

Sam Shaikh


2 Answers

In Swift 3,

 let filteredConstraints = button.constraints.filter { $0.identifier == "identifier" }
 if let yourConstraint = filteredConstraints.first {
      // DO YOUR LOGIC HERE
 }
like image 76
Venk Avatar answered Sep 17 '22 01:09

Venk


You may wish to extrapolate the logic provided in previous answer into an extension.

extension UIView {
    /// Returns the first constraint with the given identifier, if available.
    ///
    /// - Parameter identifier: The constraint identifier.
    func constraintWithIdentifier(_ identifier: String) -> NSLayoutConstraint? {
        return self.constraints.first { $0.identifier == identifier }
    }
}

You can then access any constraint anywhere using:

myView.constraintWithIdentifier("myConstraintIdentifier")

Edit: Just for kicks, using the above code, here's an extension that finds all the constraints with that identifier in all the child UIViews. Had to change the function to return an array instead of the first constraint found.

    func constraintsWithIdentifier(_ identifier: String) -> [NSLayoutConstraint] {
        return self.constraints.filter { $0.identifier == identifier }
    }

    func recursiveConstraintsWithIdentifier(_ identifier: String) -> [NSLayoutConstraint] {
        var constraintsArray: [NSLayoutConstraint] = []

        var subviews: [UIView] = [self]

        while !subviews.isEmpty {
            constraintsArray += subviews.flatMap { $0.constraintsWithIdentifier(identifier) }
            subviews = subviews.flatMap { $0.subviews }
        }

        return constraintsArray
    }
like image 31
Isaiah Turner Avatar answered Sep 21 '22 01:09

Isaiah Turner