Using Identifiers to Debug Autolayout

A quick tip I found buried in a WWDC session on Auto Layout that helps when debugging problems with constraints

Unable to Satisfy Constraints

If you have used Auto Layout you will be familiar with the log that Xcode spits out when you get something wrong. To create an example I modified my Stack View sample code and added a constraint to each of the images to give them a fixed width of 240 (not a good idea as we will see).

That works in regular width views such as the iPad but is too wide for a compact width view such as the iPhone in portrait. The console log at runtime is not fun to read. Skipping the boilerplate text you get a list of the problematic constraints:

The log then tells you which of the above constraints it has decided to break:

Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7fc1ab536ef0 H:[UIImageView:0x7fc1ab537380(240)]>

The log output uses the auto layout visual format language but it is hard to pick out my constraints from those created by the system. This is especially the case with stack views which are by design intended to create most of the constraints for you. In this trivial example I know the fixed width constraints that I just added broke things but it is hard to see that from the log and the more complex the view the harder it gets.

Adding an Identifier to a Constraint

The log gets a lot easier to understand if you add an identifier to each constraint (NSLayoutConstraint has had an identifier property since iOS 7). In Interface Builder find the constraint and add the identifier in the Attributes inspector (I am using $ as a prefix/suffix to make them stand out in the log):

Update 18-August-2015: As pointed out in the comments the identifier can only be edited in Interface Builder starting with Xcode 7. It is not visible in Xcode 6.4.

If adding the constraint in code:

constraint.identifier = "$HeartImageFixedWidth$"

It is trickier if you are using the visual format language which uses arrays of constraints. For example, consider the Swift code fragment to create a fixed width constraint for the heart image view: