When it comes to work with Auto Layout to build a complex user interface, it happens that you end up creating a huge number of constraints. Some of those constraints are needed for the main structure, some other are needed just to keep some secondary elements aligned. That said, even if you are skilled enough with Auto Layout, updating crowded user interfaces is… annoying. There isn’t a quick and easy way to go through this task and, sometimes, the risk of breaking the UI is damn high!
It seems that starting from iOS 9 the situation will be much more easier for us thanks to UIStackView class!
This class is a welcome addition to UIKit and in this tutorial we briefly go through some of the main aspects that make it so useful. Without further ado let’s start introducing the UIStackView class!
UIStackView in a few words
A UIStackView is a lightweight subclass of UIView whose main role is to act as container for other views. Thanks to this class we can easily group elements keeping them organized with a shared logic: For instance, you can create a vertical list of elements that are equally distributed through the height and aligned to the right of their container view (the Stack View). As you can see we are defining the vertical, the horizontal and the distribution behaviour at the same time. Believe it or not, you don’t have to add a single constraint! All this information are managed for you by the UIStackView, you have only to define some properties…all the rest comes for free.
The properties that define how Stack View views are organized are essentially 3: axis, distribution and alignment. We can setup those properties through Interface Builder or programmatically. Even if I’m not a fan of the Xib-way, I’ve to say that organizing user interfaces with UIStackView and Interface Builder is extremely easy and useful to maintain and update the layout in the future.
With this tutorial we make some experiments with the Stack View to understand how it works. So launch Xcode 7 and create a single page project, then open the Main.storyboard.
Create a new Stack View just dragging and dropping a vertical Stack View from the IB objects library into a view controller of the Storyboard/Xib and add some constraints to define a fixed size. Let’s say 200 X 200 and anchor the Stack View to the top left of the main view.
Now just drag and drop some Images and a UILabel inside the Stack View. As you can see the elements are some how arranged vertically within the Stack View.
(You can also create a Stack View selecting some views and just pressing the “Stack View button” in Interface Builder. The selected view will be wrapped into a new instance of Stack View).
Select the Stack View and open the Attribute editor, here you find the properties previously introduced.
The axis has only two possible values: Vertical or Horizontal and, depending on your selection, the views handled by the Stack View are distributed along the Vertical or the Horizontal axis.
Just try to switch the current example axis value to Horizontal to see how the labels will be rearranged.
Let’s check the alignment parameter. Depending on the axis, you can define how to align elements into the available space. If you select Vertical axis you can align elements to the leading, trailing and center of the stack while if the axis is horizontal, the choices are top, center or bottom. With both axis you can select the fill alignment to have the views expanding to take all the available space.
Just to continue with the previous example, you can select “Trailing” alignment to see how the elements will be moved to the right of the Stack View.
The distribution property describes how the stack elements should be distributed along the available space. The views are placed inside the Stack taking into consideration their intrinsic content size, hugging and compression priority values. Essentially you can decide to fill the available space with the stack elements or just to place those elements along the available space. The main difference is that with the former way the elements’ size should change to fit the Stack View size, with the latter way the Stack View changes only the elements positions.
The available options for fill-mode are fill, fill proportionally, fill equally. While if you prefer to displace the elements without changing any size, the possible values are Equally Spacing and Equally Center.
For the current example select “Equal Spacing” and you’ll find out that the Stack View tries to arrange its subviews adding similar margins between views edges.
You can better specify the element distribution defining also a value for the **spacing** property.
The views that are managed by the Stack View are subviews of the Stack View itself but they are also contained inside the **arrangedSubviews** array. This property is a subset of the Stack View subviews and each view that you add to this array is also added as subview of the Stack View, if you add a subview using the standard method “AddSubview” this view is not handled to the Stack View, but it might be used for example as a decoration view (you are responsible to set the view position inside the Stack View bounds).
You can add elements to the Stack View arrangedSubviews list using the addArrangedSubview method or the insertArrangedSubview(view:stackIndex:) method to better define the Stack order.
When it comes to remove a handled view from the Stack you can call the removeFromParent view’s method and the view will be removed form subviews and arrangedSubviews arrays.
A UIStackView can be managed exactly as any other UIView subclass: You might create complex structures adding a Stack View as child of another Stack View or insert it inside a Scroll View. Just keep in mind that the only constraints that you have to add are those that define how a Stack View is placed inside a parent view, and only if the parent view is not another Stack View. In that case the constraints will be created for you.
This article is just a quick introduction to the UIStackView class, but I think that it is enough to understand that this class has a huge potential! I’m pretty sure that I’m going to use it to handle the main structure of my application and those views that require a lot of constraints just to keep element aligned 😛
Feel free to poke me on twitter if you have any question!