UIStackView and Auto Layout

Alan Wang
Compass True North
Published in
7 min readJul 22, 2019

When UIStackView was first released on iOS9, it was billed as a way to use Auto Layout without creating constraints. UIStackView auto-magically lays out its arranged subviews according to the parameters you give it. While this is a convenient and useful feature, developers are sometimes confused about how UIStackView interacts with constraints imposed on either the stack view, or its subviews. What many developers don’t realize is that the only thing UIStackView does is create and manage constraints on their behalf.

There is no magic in UIStackView. All it does is create constraints.

Knowing the constraints created by your stack view allows you to understand how those constraints interact with constraints created by you. With a good understanding of Auto Layout, having the “full picture” of constraints allows you to create better layout code.

In this article, we will explore what constraints are created by UIStackView based on two key parameters: distribution and alignment. I will be using vertical stack views as an example, but the same concepts apply on the horizontal axis.

The information in this article is distilled from Alexander Grebenyuk’s Let’s Build UIStackView. If you are looking for more depth, I highly recommend reading his article.

Distribution

The first key property of UIStackView is its distribution. This property determines how the stack view lays out its views in the direction of its axis (i.e. for a vertical stack view, distribution determines the height/vertical position of its arranged subviews). There are 5 options:

  • fill (default)
  • fillEqually
  • fillProportionally
  • equalSpacing
  • equalCentering

fill

A layout where the stack view resizes its arranged views so that they fill the available space along the stack view’s axis. When the arranged views do not fit within the stack view, it shrinks the views according to their compression resistance priority. If the arranged views do not fill the stack view, it stretches the views according to their hugging priority. If there is any ambiguity, the stack view resizes the arranged views based on their index in the arrangedSubviews array.

The .fill distribution creates constraints attaching the top of the first arranged subview to the top of the stack view, and the bottom of the last arranged subview to the bottom of the stack view. It also creates a constraint between the top/bottom of adjacent subviews with the spacing of the stack view.

fillEqually

A layout where the stack view resizes its arranged views so that they fill the available space along the stack view’s axis. The views are resized so that they are all the same size along the stack view’s axis.

.fillEqually includes all of the same constraints as .fill, but additionally adds equal height constraints to all of the arranged subviews.

fillProportionally

A layout where the stack view resizes its arranged views so that they fill the available space along the stack view’s axis. Views are resized proportionally based on their intrinsic content size along the stack view’s axis.

.fillProportionally is similar to .fillEqually.Once again, it includes the same constraints as .fill, but instead of having equal height constraints like .fillEqually, it constrains the heights in proportion to a ratio. The ratio is computed using the unconstrained height of each view divided by the total unconstrained height for all views.

equalSpacing

A layout where the stack view positions its arranged views so that they fill the available space along the stack view’s axis. When the arranged views do not fill the stack view, it pads the spacing between the views evenly. If the arranged views do not fit within the stack view, it shrinks the views according to their compression resistance priority. If there is any ambiguity, the stack view shrinks the views based on their index in the arrangedSubviews array.

.equalSpacing utilizes another new class introduced in iOS9: UILayoutGuide. A layout guide is essentially an empty rectangle that you can constrain to. As always, the top of the first arranged subview and the bottom of the last arranged subview are constrained to the top/bottom of the stack view respectively. Additionally, layout guides are added and constrained to the top/bottom of adjacent arranged subviews. Finally, equal height constraints are applied to the layout guides.

equalCentering

A layout that attempts to position the arranged views so that they have an equal center-to-center spacing along the stack view’s axis, while maintaining the spacing property’s distance between views. If the arranged views do not fit within the stack view, it shrinks the spacing until it reaches the minimum spacing defined by its spacing property. If the views still do not fit, the stack view shrinks the arranged views according to their compression resistance priority. If there is any ambiguity, the stack view shrinks the views based on their index in the arrangedSubviews array.

Similar to .equalSpacing, .equalCentering adds layout guides between adjacent arranged subviews. However, .equalCentering constrains the top/bottom of each layout guide to the center of each adjacent arranged subview, rather than their top/bottom. Once again, an equal height constraint is imposed on the layout guides. Finally, constraints are created between the top/bottom of adjacent arranged subviews with a greater-than-or-equal-to requirement on the spacing of the stack view.

Alignment

The second key property of UIStackView is alignment. This property determines how the stack view lays out its views in the direction perpendicular to its axis (i.e. for a vertical stack view, alignment determines the width/horizontal position of its arranged subviews). The options are:

  • fill (default)
  • leading / top
  • trailing / bottom
  • center
  • firstBaseline / lastBaseline

fill

A layout where the stack view resizes its arranged views so that they fill the available space perpendicular to the stack view’s axis.

The simplest of the alignments, .fill constrains the leading/trailing edges of each arranged subview to the leading/trailing edge of the stack view.

leading / top

A layout for vertical stacks where the stack view aligns the leading edge of its arranged views along its leading edge. This is equivalent to the top alignment for horizontal stacks.

Not shown: Very low priority width constraint of 0.

.leading is similar to .fill, except the trailing edge’s constraints are now greater-than-or-equal-to, rather than simply equal-to. There is also a weak, optional width constraint of 0 that serves to ensure the stack view’s width will be as small as possible.

trailing / bottom

A layout for vertical stacks where the stack view aligns the trailing edge of its arranged views along its trailing edge. This is equivalent to the bottom alignment for horizontal stacks.

Not shown: Very low priority width constraint of 0.

.trailing is basically the same as .leading, except it’s the leading edges that have greater-than-or-equal-to requirements. Again, there is a weak, optional width constraint of 0 to ensure the stack view is only as wide as its widest arranged subview.

center

A layout where the stack view aligns the center of its arranged views with its center along its axis.

Not shown: Very low priority width constraint of 0.

In .center, both the leading and trailing edges have greater-than-or-equal-to constraints. Additionally, all arranged subviews also have their centers constrained to the center of the first arranged subview. Once again, there is a weak width constraint of 0.

firstBaseline / lastBaseline

A layout where the stack view aligns its arranged views based on their first/last baseline. This alignment is only valid for horizontal stacks.

No image is provided, since this alignment is only valid for horizontal stack views.

.firstBaseline and .lastBaseline are similar to .center, except instead of constraining to the center, they constrain to the first/last baselines of the arranged subviews. These baselines are determined by the forFirstBaselineLayout and forLastBaselineLayout properties of the subviews.

Closing

In summary, there is nothing magical about UIStackView. The only thing it does is create a set of constraints based on its distribution and alignment properties. Understanding those constraints will allow you to tune UIStackView to play nicely with your other constraints.

Also, for your viewing pleasure, here is every diagram on one handy sheet.

Next Steps

If you’re looking to familiarize yourself on how constraints and Auto Layout work, check out my other article How Auto Layout Works: A Conceptual Guide.

If you’re looking to get more depth on exactly what constraints are created by the system, and their priorities, check out Let’s Build UIStackView by Alexander Grebenyuk.

If you’re looking for a job, Compass is hiring.

Resources

--

--