SwiftUI Layout

SwiftUI Layout (HStack, VStack, ZStack)

Creating complex user interfaces in SwiftUI involves combining simple views together.

SwiftUI provides three primary container views that dictate how elements are arranged on the screen.

These are VStack (Vertical), HStack (Horizontal), and ZStack (Depth/Overlapping).

Mastering these three stacks is the secret to building any layout you can imagine.


VStack (Vertical Stack)

A VStack arranges its children in a vertical line, from top to bottom.

By default, a VStack centers its content, but you can change the alignment to leading or trailing.

VStack Example:

import SwiftUI

struct VerticalView: View { var body: some View { // Align items to the left (leading) with 20px spacing VStack(alignment: .leading, spacing: 20) { Text("Title") .font(.largeTitle) Text("Subtitle") .font(.subheadline) .foregroundColor(.gray) } } }


HStack (Horizontal Stack)

An HStack arranges its children in a horizontal line, from left to right.

This is perfect for placing an icon next to some text, or arranging a row of buttons.

HStack Example:

struct HorizontalView: View {
    var body: some View {
        HStack {
            Image(systemName: "star.fill")
                .foregroundColor(.yellow)
            Text("Favorites")
        }
    }
}

ZStack (Depth Stack)

A ZStack layers its children on top of one another, like a stack of pancakes.

The first item in the ZStack is at the bottom (the background), and subsequent items are placed on top.

ZStack Example:

struct DepthView: View {
    var body: some View {
        ZStack {
            // The background layer
            Color.blue.ignoresSafeArea()
            // The foreground layer
            Text("I am on top of the blue color!")
                .foregroundColor(.white)
        }
    }
}

Spacers

Stacks tightly wrap their content by default. If you want to push views apart, you use a Spacer.

A Spacer expands to fill all available empty space along the axis of its containing stack.


Exercise

Which stack should you use if you want to place a text label directly over an image background?