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:
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 toredBoxWidth
.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
Xcode 10 Build Fails with 'Command Compileswift Failed with a Nonzero Exit Code
React-Native Run-iOS Can Not Find Any Simulator
Getting Data from Each Uitableview Cells Swift
How to Detect iOS 6 and All Minor Versions by User Agent
How to Access an Xcassets Directory on the Filesystem
Fix Cordova Geolocation Ask for Location Message
Cabasicanimation Rotate Returns to Original Position
Xcode Warning When Using Mapkit and Corelocation
How to Launch the iOS Simulator from Terminal
Watchkit Extension Bundle Identifiers
Open Links in Safari Instead of Uiwebview
An Elegant Way to Ignore Any Errors Thrown by a Method
Avspeechsynthesizer in Background Mode
Apple Llvm 6.0 Error: Clang Failed with Exit Code -1
Get Dns Server Ip from iPhone Settings
Location Access - App Is Not Asking for User Permission to Access Location - iOS 11
Uiscrollview Pauses Nstimer While Scrolling
How to Send Data from iPhone to Apple Watch in Os2 in Objective-C