NEW: Nominations are now open for the 2019 Swift Community Awards! >>

Using stacks to arrange views

Paul Hudson    @twostraws   

When we return some View for our body, we mean “one specific type that conforms to the View protocol. That might be a navigation view, a form, a text view, a picker, or something else entirely, but it’s always exactly one thing that conforms to the View protocol.

If we want to return multiple things we have various options, but three are particularly useful. They are HStack, VStack, and ZStack, which handle horizontal, vertical, and, er, zepth.

Let’s try it out now. Our default template looks like this:

var body: some View {
    Text("Hello World")
}

That returns precisely one kind of view, which is a text view. If we wanted to return two text views, this kind of code simply isn’t allowed:

var body: some View {
    Text("Hello World")
    Text("This is another text view")
}

Instead, we need to make sure SwiftUI gets exactly one kind of view back, and that’s where stacks come in: they allow us to say “here are two text views, and I want them to be positioned like this…”

So, for VStack – a vertical stack of views – the two text views would be placed one above the other, like this:

var body: some View {
    VStack {
        Text("Hello World")
        Text("This is inside a stack")
    }
}

By default VStack places little or no spacing between the two views, but we can control the spacing by providing a parameter when we create the stack, like this:

VStack(spacing: 20) {
    Text("Hello World")
    Text("This is inside a stack")
}

Just like SwiftUI’s other views, VStack can have a maximum of 10 children – if you want to add more, you should wrap them inside a Group.

By default, VStack aligns its views so they are centered, but you can control that with its alignment property. For example, this aligns the text views to their leading edge, which in a left-to-right language such as English will cause them to be aligned to the left:

VStack(alignment: .leading) {
    Text("Hello World")
    Text("This is inside a stack")
}

Alongside VStack we have HStack for arranging things horizontally. This has the same syntax as VStack, including the ability to add spacing and alignment:

HStack(spacing: 20) {
    Text("Hello World")
    Text("This is inside a stack")
}

Vertical and horizontal stacks automatically fit their content, and prefer to align themselves to the center of the available space. If you want to change that you can use one or more Spacer views to push the contents of your stack to one side. These automatically take up all remaining space, so if you add one at the end a VStack it will push all your views to the top of the screen:

VStack {
    Text("First")
    Text("Second")
    Text("Third")
    Spacer()
}

If you add more than one spacer they will divide the available space between them.

We also have ZStack for arranging things by depth – it makes views that overlap. In the case of our two text views, this will make things rather hard to read:

ZStack {
    Text("Hello World")
    Text("This is inside a stack")
}

ZStack doesn’t have the concept of spacing because the views overlap, but it does have alignment. So, if you have one large thing and one small thing inside your ZStack, you can make both views align to the top like this: ZStack(alignment: .top) {.

ZStack draws its contents from top to bottom, back to front. This means if you have an image then some text ZStack will draw them in that order, placing the text on top of the image.

Try placing several horizontal stacks inside a single vertical stack – can you make a 3x3 grid?

LEARN SWIFTUI FOR FREE I have a massive, free SwiftUI video collection on YouTube teaching you how to build complete apps with SwiftUI – check it out!

MASTER SWIFT NOW
Buy Testing Swift Buy Practical iOS 12 Buy Pro Swift Buy Swift Design Patterns Buy Swift Coding Challenges Buy Server-Side Swift (Vapor Edition) Buy Server-Side Swift (Kitura Edition) Buy Hacking with macOS Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with Swift Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Beyond Code

Was this page useful? Let us know!

Average rating: 4.8/5