1. Code
  2. Mobile Development
  3. iOS Development

iOS 9: Getting Started with UIStackView

Scroll to top

Like every iteration of iOS, iOS 9 brings forth a lot of new features. UIKit changes with every release of iOS, but one particular addition in iOS 9 will change how developers fundamentally think about creating user interfaces on iOS, UIStackView. In this tutorial, you will learn how to use UIStackView to create user interfaces.

This article assumes you are familiar with the basics of Auto Layout. If this subject is new to you, then our introductory tutorial about Auto Layout is a good place to start. To understand why stack views are so helpful and how they operate, a solid understanding of Auto Layout is required.

1. Demo Preview

Using UIStackView, we are going to build a mock screen that prompts the user to leave a rating for their app. The user can add or remove stars in the user interface to indicate their rating. It will look like this when we are finished.

This is what the result will look likeThis is what the result will look likeThis is what the result will look like

Download the starter project from GitHub and open it. You'll see that there are two stack views inside Main.Storyboard.

This is the storyboard of the starter projectThis is the storyboard of the starter projectThis is the storyboard of the starter project

We will use the two stack views to lay out the user interface. Before we begin coding, let's first take brief look at how a stack view works.

2. UIStackView Overview

At its core, the stack view is an interface for laying out several subviews, either vertically or horizontally. If you have Android development experience, it's similar to the LinearLayout control.

One of the main advantages of the stack view is that it will automatically create Auto Layout constraints for each subview that's added to it. You also have finite control over how those subviews are sized and positioned. There are options to configure the sizing of the views, where they should be arranged, as well as how much padding should be between the subviews.

Laying Out Content

To see the options of a stack view, open Main.Storyboard and select one of of the stack views. In the Attributes Inspector, notice the options listed under Stack View.

The options of a stack viewThe options of a stack viewThe options of a stack view

The Axis determines if the stack view arranges its subviews horizontally or vertically. The Alignment controls how the actual subviews should be aligned. Distribution defines how the subviews are sized and Spacing controls the minimum spacing between the subviews of the stack view.

To simplify these terms, think of it like this. Alignment controls the X and Y values while Distribution controls height and width. The other two values can also affect alignment. Baseline Relative, if checked, will derive vertical spacing of each subview from its baseline. Layout Margins Relative places the subviews relative to the standard layout margins if selected.

Another important thing to remember when working with a stack view is that it's built to be a container view. Because of that, it's a nonrendering subclass of UIView. It's not draw to the canvas like other UIView subclasses. This means that setting properties like backgroundColor or overriding the drawRect: method will have no effect on the stack view.

subviews and arrangedSubviews

Before we start working with stack views, I'd like to focus on the difference between a stack view's subViews and arrangedSubviews properties. If you wish to add a subview for the stack view to manage, you do so by calling addArrangedSubview: or insertArrangedSubview:atIndex:. The arrangedSubViews array is a subset of its subViews property.

To remove a subview that the stack view manages, you need to call both removeArrangedSubview: and removeFromSuperview. Removing an arranged subview ensures the stack view will no longer manage that view's constraints. It doesn't take it out of the view hierarchy. This is very important to remember.

Now that we have a solid understanding of how the stack view works, let's start using a stack view.

3. Configuring the Vertical Stack View

Open Main.Storyboard and select the top stack view. In the Attributes Inspector, make the following changes:

  • set Alignment to Center
  • set Distribution to Equal Spacing
  • set Spacing to 30

This will tell the stack view to try and add constraints that center all of the subviews vertically and size them so that they fill the stack view's axis evenly. In addition, it will add 30 points of padding to the subviews.

If the subviews are not able to fit inside the stack view, it will shrink them based on their respective compression resistance priorities. This could happen if you were to add subviews to the stack view at run time as we'll see later.

If there is any ambiguity, the stack view will fall back to shrinking the subviews based on their index in its arrangedSubviews array until they fit the stack view's bounds.

4. Adding Vertical Stack Subviews

Add a label, an image view, and a button to the top stack view by dragging them in the document outline. Ensure the label is at the top, the image view in the middle, and the button at the bottom. The storyboard's document outline should look like this after you've added these subviews:

Adding subviews to the top stack viewAdding subviews to the top stack viewAdding subviews to the top stack view

Next, we'll need to edit some of the properties of the subviews we just added, using the Attributes Inspector. For the label, change its Text to "How do you like our app?" and select Center for Text Alignment. As for the image view, enter "logo" for the Image and Aspect Fit for the Content Mode. For the button, set its Text to "Add Star!".

Go ahead and run the app. You'll see that with very little work, you have added three subviews that respond to any changes in orientation, size class, etc. In fact, you didn't even have to manually add any constraints.

While the app is running, click the Debug View Hierarchy button at the bottom of the Xcode window to initiate live view debugging.

Live view debugging in XcodeLive view debugging in XcodeLive view debugging in Xcode

Select any of the three subviews you added earlier. Look at the size inspector and notice the constraints that were added by the stack view. The picture below is showing the constraints added for the button.

The Auto Layout constraints of the stack views buttonThe Auto Layout constraints of the stack views buttonThe Auto Layout constraints of the stack views button

5. Adding Stars

The button to add stars for our mock app isn't hooked up yet. Let's fix that now. Stop the app and open the storyboard. Create an IBAction with a name of addStar for the Touch Up Inside event.

Adding an IBActionAdding an IBActionAdding an IBAction

Add the following code inside the addStar(_:) method:

1
@IBAction func addStar(sender: AnyObject) {
2
    let starImgVw:UIImageView = UIImageView(image: UIImage(named: "star"))
3
    self.horizontalStackView.addArrangedSubview(starImgVw)
4
    UIView.animateWithDuration(0.25, animations: {
5
        self.horizontalStackView.layoutIfNeeded()
6
    })
7
}

We add a star image to the horizontal stack view with an animation. Remember, since stack views manage Auto Layout constraints for us, we only need to call layoutIfNeeded to create an animation.

Build and run the app again and add a star. You'll see that the end result is not what we were hoping for.

This is not what we were hoping forThis is not what we were hoping forThis is not what we were hoping for

If you look at the Attributes Inspector with the bottom stack view selected, the problem should be clear. Since both the Alignment and Distribution are set to Fill, the stack view is stretching the star to fill its bounds.

This will also cause more problems when more stars are added. We want the stars to be centered, not stretched to fit the width of the stack view. Change Alignment to Center and Distribution to Fill Equally. Finally, update the addStar(_:) method by setting the image view's Content Mode to Aspect Fit.

1
@IBAction func addStar(sender: AnyObject) {
2
    let starImgVw:UIImageView = UIImageView(image: UIImage(named: "star"))
3
    starImgVw.contentMode = .ScaleAspectFit
4
    self.horizontalStackView.addArrangedSubview(starImgVw)
5
    UIView.animateWithDuration(0.25, animations: {
6
        self.horizontalStackView.layoutIfNeeded()
7
    })
8
}

Build and run the app one more time. Add a few stars and notice how the stack view correctly centers them along its axis.

This looks much betterThis looks much betterThis looks much better

6. Nesting Stack Views

Our app wouldn't be very helpful without the ability to remove stars. Open the storyboard and add a horizontal stack view to the top stack view's view hierarchy. Make sure it's positioned below the image view for the logo and above the button.

Adding a stack view to another stack viewAdding a stack view to another stack viewAdding a stack view to another stack view

Drag the "Add Star!" button inside the newly added stack view and add second button to the new stack view. Change the button's title to "Remove Star" and select red for the text color. The document outline should now look like this:

The new stack view contains two buttonsThe new stack view contains two buttonsThe new stack view contains two buttons

Edit the attributes of the new stack view in the Attributes Inspector, making the following changes:

  • set Alignment to Center
  • set Distribution to Equal Spacing
  • set Spacing to 10
Adjusting the attributes of the new stack viewAdjusting the attributes of the new stack viewAdjusting the attributes of the new stack view

7. Removing Stars

Create an IBAction for the "Remove Star" button with a name of removeStar for the Touch Up Inside event.

Create an action for the removeStar buttonCreate an action for the removeStar buttonCreate an action for the removeStar button

Add the following code to the removeAction(_:) method:

1
@IBAction func removeStar(sender: AnyObject) {
2
    let star:UIView? = self.horizontalStackView.arrangedSubviews.last
3
    if let aStar = star
4
    {
5
        self.horizontalStackView.removeArrangedSubview(aStar)
6
        aStar.removeFromSuperview()
7
        UIView.animateWithDuration(0.25, animations: {
8
            self.horizontalStackView.layoutIfNeeded()
9
        })
10
    }
11
}

Build and run the app. You should now be able to both add and remove stars. Change the orientation of the iOS Simulator or rotate your testing device to see how the app behaves by adjusting its user interface. Remember that we've built the the user interface of this app without having to manually add a single constraint.

Keep in mind that the removeFromSuperview call in the removeStar(_:) method is essential to remove the subview from the view hierarchy. Recall that removeArrangedSubview(_:) only tells the stack view that it no longer needs to manage the subview's constraints. The subview, however, remains in the view hierarchy until we remove it from its superview by calling removeFromSuperview on it.

Conclusion

The UIStackView class greatly simplifies developing user interfaces. This is a good thing, especially when the hardware the application runs on can vary so much. With UIStackView, developers can spend less time setting up tedious constraints for simple scenarios, shifting the heavy lifting to UIKit.

If you got stuck at any point during this tutorial, feel free to download the finished project from GitHub.

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.