Skip to content

Stacks on Stacks

Posted on:March 21, 2023

Before we can build our own views, we have to understand what our basic components are. While we could start with Text, Image, or others — we should really start with the most powerful (and likely most commonly used) tools: HStack and VStack. As in UIKit, stacks should probably be the first thing reached for in starting a new UI.

HStack and VStack are views that can arrange their subviews in a horizontal or vertical line, and are roughly equivalent to UIKit’s UIStackView. Both HStack and VStack have three main properties that affect their layout:

Using Stacks

HStack and VStack are very versatile views that can be used to create various layouts. They can be nested inside each other or inside other container views to create complex and beautiful layouts.

Basic Usage

HorizontalVertical
horizontalvertical

Basic usage of these is as simple as declaring them and giving them child views.

HStack {
  Text("Hello")
  Text("World")
  Text("!")
}

VStack {
  Text("Hello")
  Text("World")
  Text("!")
}

This lays out the views horizontally or vertically, respectively, laid out across the center line of the secondary axis. While we haven’t gone over the Text view yet, for now, we can view it as a simple and easy way of displaying a single block of text on the screen.

Cards

cards We can use stacks to display cards:

VStack(alignment:.leading) {
  Image("dog")
    .resizable()
    .aspectRatio(contentMode:.fit)

  Text("Meet Pepper!")
    .font(.title)
    .padding()

  Text("Pepper is a sassy super-mutt that loves to play.")
}
.padding()
.background(Color.white)
.shadow(radius: 10)

This example is much more visually interesting, partially because one of my dogs, Pepper, is in it. This example uses a VStack to arrange three subviews: an Image view, and two Text views. In this instance, the VStack has a leading alignment parameter, which means that the subviews are aligned along the left edge of the VStack (in a right to left language, such as Arabic, it would be the right edge of the stack).

The stack has some modifiers applied to it as a whole. It has a padding modifier that adds the system default amount of space around it and its subviews. The background modifier sets its background color to white. And it has a shadow modifier that adds a shadow effect around the card. The result is a view that can function as a standalone card in an application.

Forms

form

VStack(alignment: .leading) {
  Text("Name")
    .font(.headline)
    .padding(.bottom)

  TextField("Enter your name", text: $name)
    .textFieldStyle(.roundedBorder)
    .padding(.bottom)

  Text("Email")
    .font(.headline)
    .padding(.bottom)

  TextField("Enter your email", text: $email)
    .textFieldStyle(.roundedBorder)
    .padding(.bottom)

  Button(action: { }) {
    Text("Submit")
      .font(.headline)
      .foregroundColor(.white)
      .padding()
      .background(Color.blue)
      .cornerRadius(10)
  }
}
.padding()

This example uses a VStack to arrange six subviews: two Text views, two TextField views, and one Button view. We haven’t touched on the TextField or Button views yet, but in short: a TextField is a user interactive bit of Text, and a Button is a user-interactive view that accepts some action which can perform some logic (submitting a form, making a network request, etc.)

Limitations of Stacks

HStack and VStack are powerful views that can handle most layout scenarios, but like anything else, they have their limitations:

Ultimately, these limitations aren’t dealbreakers and should require only a little extra work or creativity to overcome. In the future, we’ll examine some techniques and strategies to work around these issues in greater detail.