Easier Auto Layout with Stack Views

Last updated: Nov 10, 2022

The WWDC 2015 session 218 Mysteries of Auto Layout, Part 1 makes a bold claim for the UIStackView class introduced in iOS 9:

Start with Stack View, use constraints as needed

At first glance the stack view is a simple class that allows you to layout views in either a column or a row. What makes it powerful is that it applies Auto Layout to the views without you having to add the constraints. You can also embed stack views in other stack views to build up complex layouts with hopefully minimal Auto Layout pain.

For example, the Storyboard below has two horizontal rows of views centered in the superview and pinned to the top layout guide:

This is not so complicated a layout but manually specifying the constraints either in Interface Builder or in code is still non trivial. To layout this view with stack views:

  • Select the UILabel and UISwitch views that make up the first row and from the Xcode Editor menu use Embed In > Stack View (you can also drag stack views from the object library and drop views onto them). Using the Inspector check the axis is “Horizontal”, set the alignment to “Center”, keep the default “fill” distribution and increase the spacing between the views to “16”:

  • Repeat the above steps to embed the two image views in a horizontal stack view again with a center alignment with some spacing between the views.

  • Now select the two stack views and embed them in a stack view. Interface Builder seems to be smart enough to guess that this time we want a vertical stack view:

  • Finally we do need to add some minimal constraints to fix the position of the top stack view. In this example there is no reason to constrain the sizes of the stack views as they are sized based on the intrinsic content sizes of the subviews. Two constraints are needed to center the stack view in the superview and pin it to the top layout guide. The final view hierarchy is shown below for reference:

Note that the order the views are added to the stack view are important. The first view in the stack view array arrangedSubviews property is pinned to the leading edge of the stack and the last view is pinned to the trailing edge. The alignment, distribution and spacing properties control the layout along the axis of the stack view.

Dynamically updating a Stack View

A cool feature of the stack view is that it automatically updates its layout when views are added or removed from the arrangedSubviews array. Hiding a view is also sufficient for it to be removed from the layout constraints. Changes to the stack view properties can also be animated using the same technique we saw in Animating Autolayout Constraints.

For example if we connect the UISwitch to an action we can animate switching between a horizontal or vertical layout of the image views:

@IBAction func axisChange(_ sender: UISwitch) {
  UIView.animate(withDuration: 1.0, animations: {
    self.updateConstraintsForAxis()
  })
}

The updateConstraintForAxis function just sets the axis of the stack view containing the two image views:

private func updateConstraintsForAxis() {
  if (axisSwitch.isOn) {
    stackView.axis = .horizontal
  } else {
    stackView.axis = .vertical
  }
}

The animated gif below gives you an idea of how this appears:

Get the Code

The full sample Xcode project is available in my GitHub repository.