How to Add an Identifier to Auto Layout Constraints in Interface Builder

How to use constraint Identifiers in autolayout and how to change constrain using identifiers? [Swift]

HOW: The identifier is useful when debugging (e.g. constraints not matching and one of them gets broken at run time; the constraint identifiers are being shown in log so you can see which one might cause problems)

WHY: Constraint identifiers make logs easier to read, more accurate and they save you a lot of time.

Constraint editing: If you want to change constraints programmatically you will have to declare them as outlets (like a label or button), then remove them from the view (NOT the object itself) and then set them again to the view. From my knowledge you can't just "edit" the constraints programmatically.

Your code gives you only width and height because you access the view's constraints which only contains the objects' widths and heights.

Is there a way to add an identifier to Auto Layout Constraints in Interface Builder?

Update:

As explained by Bartłomiej Semańczyk in his answer, there is now an Identifier field visible in the Attributes Inspector for the NSLayoutConstraint making it unnecessary to expose this field yourself. Just select the constraint in the Document Outline view or in the Storyboard view and then add an identifier in the Attributes Inspector on the right.


Earlier Answer:

Yes, this can be done. NSLayoutConstraint has a property called identifier than can be exposed in Interface Builder and assigned. To demo this, I created a Single View Application that has a single subview that is a red box. This subview has 4 constraints: width, height, centered horizontally in container, centered vertically in container. I gave the width constraint the identifier redBoxWidth by doing the following:

  1. Click on the width constraint in the Document Layout View. Then in the Identity Inspector under User Defined Runtime Attributes, click on the + under Key Path. Change keyPath to identifier, change the Type Boolean to String, and set the Value to redBoxWidth.

    naming a constraint

  2. Then in ViewDidLoad it is possible to find the constraint by name and change its value:

    class ViewController: UIViewController {

    override func viewDidLoad() {
    super.viewDidLoad()

    for subview in view.subviews as [UIView] {
    for constraint in subview.constraints() as [NSLayoutConstraint] {
    if constraint.identifier == "redBoxWidth" {
    constraint.constant = 300
    }
    }
    }
    }
    }

How to use constraint Identifiers in autolayout and how to change constrain using identifiers? [Swift]

HOW: The identifier is useful when debugging (e.g. constraints not matching and one of them gets broken at run time; the constraint identifiers are being shown in log so you can see which one might cause problems)

WHY: Constraint identifiers make logs easier to read, more accurate and they save you a lot of time.

Constraint editing: If you want to change constraints programmatically you will have to declare them as outlets (like a label or button), then remove them from the view (NOT the object itself) and then set them again to the view. From my knowledge you can't just "edit" the constraints programmatically.

Your code gives you only width and height because you access the view's constraints which only contains the objects' widths and heights.

How do I add an identifier to auto layout anchor constraints?

Your code returns you constraint, so you can add identifier to it like this

let myConstraint = view.heightAnchor.constraint(equalToConstant: 60.0)
myConstraint.identifier = "myIdentifier"
myConstraint.isActive = true

Find out who adds a specific auto layout constraint

If the layout is ambiguous or unsatisfiable, you can put a symbolic breakpoint on UIViewAlertForUnsatisfiableConstraints.

You can add a Debugger Command containing po [[UIWindow keyWindow] _autolayoutTrace] for Objective-C or expr -l objc++ -O -- [[UIWindow keyWindow] _autolayoutTrace] for Swift which automatically prints the UIView hierarchy, as desribed in this article.

You can also use po $r15 in the debugger to print the "details description of constraint that is broken" or po $r14 for "more detailed description of all constraints added in addition to breaking constraint", as described in this article.

If not, you can set the accessibilityIdentifier for your UIView (or directly in the IB) which will show up in the previous expressions' results (and other places too) instead of the string UIView.

Get reference to NSLayoutConstraint using Identifier set in storyboard

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
}

How to update the constant height constraint of a UIView programmatically?

Select the height constraint from the Interface builder and take an outlet of it. So, when you want to change the height of the view you can use the below code.

yourHeightConstraintOutlet.constant = someValue
yourView.layoutIfNeeded()

Method updateConstraints() is an instance method of UIView. It is helpful when you are setting the constraints programmatically. It updates constraints for the view. For more detail click here.

NSLayoutAnchor and constraint identifier

Yes you can. The apple docs say:

The NSLayoutAnchor class is a factory class for creating NSLayoutConstraint objects using a fluent API. Use these constraints to programatically define your layout using Auto Layout.

So NSLayoutAnchor is just a class that creates constraints for you instances of this class are not constraints.
An example:

subview.leadingAnchor.constraintEqualToAnchor(margins.leadingAnchor).identifier = "myIdentifier"


Related Topics



Leave a reply



Submit