Have you completed an entire app without ever deviating from the default constraint priority of 1000?

Let’s take a look at an example of when you can leverage the ability to lower the constraint priority. Before we start, an optional two paragraph refresher on how Auto Layout uses the constraint priority values.

When you accept the default value of 1000 for a constraint, that means the constraint is required, or in other words, you are telling Auto Layout that the constraint must be satisfied. If Auto Layout cannot satisfy one or more required constraints, you will see error(s) in the console indicating constraints that Auto Layout had to break and exclude from the resulting layout.

When you lower the value to anything other than 1000, that marks the constraint as optional. Auto Layout still tries to satisfy even optional constraints, but will skip them if it cannot. If there is any ambiguity in the layout, those optional constraints can be used to influence the layout and select a solution that comes as close as possible to the specified optional constraint values. In general, Apple recommends that optional constraints cluster around the defined low (250), medium (500), and high (750) values, versus being randomly all over the place.

In this particular case study, let’s say that we have a square logo, and we want to display it as large as possible on the screen, in portrait and landscape. Obviously it should always have the same width and height given that it is a square image. Our requirement means the logo would touch the sides in portrait, and touch the top and bottom in landscape.

I’ll start with a standard Single View Application from the template, and add a UIImageView to the Storyboard. I add a fictitious logo of my iOS Insight website to the project and specify it as the Image for the UIImageView. This is what it looks like initially without any constraints, and with the default View > Mode value of Scale To Fill for the UIImageView.

Currently the image is skewed and not a square. Let’s set the Mode to Aspect Fit so that any scaling maintains the height to width ratio. With this setting, the image is scaled within the UIImageView so that it fits, while respecting the aspect ratio, and any extra space is transparent. You can see exactly that below, where the image used up all the vertical space, which then constrained how wide it could be in order to maintain the height to width ratio. This left some horizontal space within the UIImageView after scaling.

Note: It could be left as Scale To Fit, and when all the constraints in this example were defined, it would be the equivalent of an Aspect Fit setting, but I’ll approach it methodically and intuitively set it to Aspect Fit at this point.

There are a few obvious constraints and settings we would want to specify before we think about ones that would be lower priority. Let’s center the image horizontally and vertically, and also set an Aspect Ratio Constraint, similar to the Mode, to specify that we want the image to maintain height/width ratio. Set the Aspect Ratio Constraint Multiplier to 1:1. After fixing the misplacement of views, we now have the following accomplished.



At present, there are no warnings or errors reported because Auto Layout is using the intrinsic size of the UIImageView to determine the size based on the image size, and it is centered in the view. Running it now successfully centers the image in portrait and landscape, but it doesn’t fill the screen as we want it to because there are no constraints that pull it to the edges in either direction.

There are multiple ways now that we can accomplish making the view be at its maximum size possible in portrait and landscape while still maintaining the height to width ratio. The first one we’ll try is adding two constraints, one that says make the UIImageView width match the superview width, and the other specifying that the height of the UIImageView matches the superview height. You might be thinking this won’t work, but lets just see what it does. Here is the list of constraints with those two added.

When run with these constraints, it actually does look correct and is the full width of the screen or height of the screen depending on whether the device is in portrait or landscape.

This is good, but in the console you can see that Auto Layout had to break a constraint to arrive at a display, and when rotated, it had to do that again.

That part is not good and it is a dangerous path to walk on. In this case we got lucky, because we have a view with one main component in it and few constraints. However, you would not want to ship an app that is in this state. As you have more and more components in a view under these circumstances, the more trouble you would likely be in, since it isn’t determinate as to how Auto Layout will resolve unsatisfiable constraints when there are several.

There is a better way, and this is where constraint priority comes into play.

Let’s revisit what we really want. In portrait, we want the image width to match the superview width. In landscape, we want the image height to match the superview height. If Auto Layout uses the width constraint, we don’t want it to use the height constraint, and vice versa. We can achieve this by lowering the priority of each of them. Auto Layout will try to satisfy both, but given the required aspect ratio constraint, in this case it will skip the optional height or width constraint that cannot be satisfied. Auto Layout would be happy having followed the rules, and there would be no errors or warnings.

I’ll update the height and width equal to superview constraints and set them both to Priority = 750. I could provide any other numbers in this example, as long as they are equal. The Storyboard will look as follows, where you can see the two priority values of 750.

This is the final result of running, rotating, and observing the clean console.



There are many other ways of using lower priority constraints, and even for this example there are other ways to accomplish the same thing with optional priority values and different constraints. Alternatively, you could use size classes and define required constraints for different size classes, but certainly in this particular scenario two optional constraints is a quick and easy way to accomplish the objective.

You can find this project in GitHub.

Hopefully this walkthrough has provided some insight as to when you might use optional constraints.