avatarYuchen Z.

Summary

The web content provides an in-depth explanation of UIStackView in iOS development, focusing on the distinction between distribution and alignment properties.

Abstract

UIStackView is a crucial UIKit component introduced in iOS 9 that simplifies layout constraints management for iOS developers. The article delves into the nuances of two key properties of UIStackView: distribution and alignment. Distribution settings include fill, fillEqually, fillProportionally, equalSpacing, and equalCentering, each affecting the size and spacing of subviews differently. Alignment settings such as fill, top, firstBaseline, center, bottom, and lastBaseline determine the positioning of subviews within the stack view. The article uses visual examples to illustrate these properties, highlighting the importance of understanding the intrinsic content size for proper layout behavior. The author also touches on the confusion that might arise with certain alignment settings like firstBaseline and lastBaseline and provides a link to a Stack Overflow answer for further clarification.

Opinions

  • The author suggests that UIStackView significantly eases the development process by reducing the need for manual constraint creation.
  • There is a hint of humor regarding the late introduction of UIStackView by Apple, comparing it to Android's LinearLayout which was available much earlier.
  • The author expresses that despite the convenience of UIStackView, developers may still struggle with its complexity, particularly with distribution and alignment settings.
  • The author indicates that the default behavior of the fill distribution setting might not be intuitive for developers because it resizes only one subview based on hugging priority.
  • The article implies that the equalCentering and equalSpacing distribution settings might appear similar, but they have distinct behaviors that become evident with varied subview sizes.
  • The author admits to finding the firstBaseline and lastBaseline alignment settings confusing and acknowledges that their utility may not be immediately apparent.
  • The article concludes with a teaser challenge for the reader to guess the stack view settings used in a provided example, fostering reader engagement and encouraging practical application of the concepts discussed.

UIStackView: Distribution vs. Alignment

UIStackView simplifies the view layout by reducing the number of constraints

Photo by Annie Spratt on Unsplash

Introduction

UIStackView is one of the most important and powerful UIKit components introduced in iOS 9. It is so powerful and elegant that it really speeds up a lot of us pushing to drop support for iOS 8.

For people that work with Auto Layout a lot, you will know that it is not particularly fun and easy to create NSLayoutConstraints. Since each view on a 2D screen has four degrees of freedom, it means that, in general, we would have to create at least four constraints for each view.

So, back to the introduction of stack view, was it that much of an innovation?

Not really, since Android’s equivalent LinearLayout was introduced at the beginning of the universe (a.k.a. API level 1). Not sure why it took Apple eight years to introduce this component.

But anyway, we are all very happy that it is finally available.

Even though UIStackView simplified the view layout a lot by reducing the number of constraints that we would have to implement otherwise, it can still get pretty complicated and somewhat confusing.

There are four main properties for a stack view:

The first one and the last one are relatively straightforward. We use axis to define the orientation of the stack view, which can either be vertical or horizontal. (If a stack is turned sideways, it should no longer be called a stack, or should it 🤔?) For the last one, spacing, as implied by the name, it specifies the spacing between views inside the stack view. How about the remaining two: distribution and alignment?

Although UIStackView has become so popular and so commonly used in so many applications, many people may not understand it fully and may not be using it right.

That’s what we will focus on today. We will compare various distribution and alignment settings and see how they differ from one another.

Preparation

Before we get started, we need to create a few dummy views to put into our stack view. Here we go:

let redDummy = DummyBoxView(width: 40, height: 40, color: .red)
let greenDummy = DummyBoxView(width: 30, height: 80, color: .green)
let blueDummy = DummyBoxView(width: 80, height: 30, color: .blue)

The implementation of DummyBoxView is very simple. There is a dashed border, in the middle, there is a label indicating the relative width and height.

As mentioned earlier, there are two axes (orientations) for a stack view: horizontal or vertical. But for simplicity, we will only focus on the horizontal stack view for now.

For a vertical stack view, we just need to turn our head by 90 degrees, right?

Distribution

The possible configurations for distribution are:

  • fill
  • fillEqually
  • fillProportionally
  • equalSpacing
  • equalCentering

Let’s just look at what they look like:

The upper two graphs are equalCentering (left) and equalSpacing (right). Their differences are not very obvious, especially when the sizes for the subviews are similar.

For equalCentering, the subviews are placed so that center-to-center spacing between views is the same. For equalSpacing, the spacings between views are the same.

The lower three graphs are fillEqually (left), fillProportionally (middle), fill (right).

Notice that for these three settings, the subviews are all resized in some way to fill the stack view. fillEqually and fillProportionally should be pretty clear according to their names. fillEqually means that all the subviews will be resized so that they are all the same width (for horizontal stack view). fillProportionally on the other hand, will resize the subviews proportionally based on their size.

But, what happens with just fill? Why is our red box so much wider?

With fill, the stack view will choose one subview to resize.

In this case, the stack view will pick the subview with the lowest hugging priority. As we never explicitly set it, all the subviews have the same default hugging priority. When this happens, the stack view will choose the first one to stretch. In this case, the red one gets stretched, while green and blue get to keep their size.

One last thing that is important to know about these three fill* settings is that the stack view uses the intrinsic content size of the subview for the calculations. Not the frame size! Not the constraint size!

Are you curious as to why all of them align to the bottom of the stack views? Let’s move on to the next section.

Alignment

The possible configurations for alignment are:

  • fill
  • top
  • firstBaseline
  • center
  • bottom
  • lastBaseline

There are actually two more, leading and trailing, that we are going to ignore for now, as they are for a vertical stack view only.

The first three are pretty clear: they are bottom (upper left), center (upper middle), and top(upper right). As you may guess, in the previous section, all the graphs are actually using the bottom alignment.

The next one is fill (lower left), where the stack view resizes all its views so that they fill the available space perpendicular to the stack view’s axis.

The last two are the most confusing: firstBaseline (lower middle) and lastBaseline (lower right). Not sure we can get much by just the names.

Let’s look at the official definitions:

  • firstBaseline: A layout where the stack view aligns its arranged views based on their first baseline.
  • lastBaseline: A layout where the stack view aligns its arranged views based on their last baseline.

The definition is similar to when I ask you what a “matchbox” is and you tell me it is a “match box”. Let’s look at one more set of examples with more subviews.

  • firstBaseline (left) is similar to top where all the subviews are top-aligned. However, they are placed at the bottom of the stack view.
  • lastBaseline (right) is similar to bottom where all the subviews are bottom-aligned. However, they are placed at the top of the stack view.

It is a bit hard for me to visualize how this would be useful. But apparently, it makes sense for aligning multi-line text views. We won’t go into more detail here. But if you are interested, this answer on stackoverflow explains it well.

How About the Vertical Stack View?

Actually, everything is still pretty much the same. The only little thing is that top and bottom should be replaced by leading and trailing. They are, under the hood, the same integers in the enum.

The End

Alright, that’s all for the stack view. Finally, can you guess what the settings are for this stack view?

  • Hint 1: It is not bottom alignment.
  • Hine 2: There is one invisible view.

As always, thanks for reading! Demo code available on GitHub with the complete set of examples.

iOS
Stack View
UI
Programming
Apple
Recommended from ReadMedium