Articles, podcasts and news about Swift development, by John Sundell.

Swift clip: SwiftUI stacks and spacers

Published on 19 Feb 2020

Let’s take a look at how SwiftUI’s various stacks and spacers can be used to achieve many kinds of flexible, adaptive layouts with very little code. While SwiftUI does include several more advanced layout APIs, stacks and spacers are a great starting point for most UIs.

Architecting SwiftUI apps with MVC and MVVM

Architecting SwiftUI apps with MVC and MVVM: Although you can create an app simply by throwing some code together, without best practices and a robust architecture, you’ll soon end up with unmanageable spaghetti code. Learn how to create solid and maintainable apps with fewer bugs using this free guide.

Sample code

A simple SwiftUI view that renders a text at the center of its parent container:

struct ContentView: View {
    var body: some View {
        Text("SwiftUI")
    }
}

Adding another text, and wrapping those two subviews within a VStack to render them on top of each other along the Y-axis:

struct ContentView: View {
    var body: some View {
        VStack {
            Text("SwiftUI")
            Text("Layout")
        }
    }
}

Pushing our two texts to the top of the screen using a Spacer:

struct ContentView: View {
    var body: some View {
        VStack {
            Text("SwiftUI")
            Text("Layout")
            Spacer()
        }
    }
}

Moving our texts to the top-left corner (or technically, top-leading corner), using an HStack and another Spacer:

struct ContentView: View {
    var body: some View {
        HStack {
            VStack {
                Text("SwiftUI")
                Text("Layout")
                Spacer()
            }
            Spacer()
        }
    }
}

Adding padding to our view using the .padding() modifier:

struct ContentView: View {
    var body: some View {
        HStack {
            VStack {
                Text("SwiftUI")
                Text("Layout")
                Spacer()
            }
            Spacer()
        }.padding()
    }
}

Adding an image rendered at the top-right (trailing) corner of the screen:

struct ContentView: View {
    var body: some View {
        HStack(alignment: .top) {
            VStack {
                Text("SwiftUI")
                Text("Layout")
                Spacer()
            }
            Spacer()
            Image(systemName: "star")
        }.padding()
    }
}

Extracting our current views into a new View type:

struct TopView: View {
    var body: some View {
        HStack(alignment: .top) {
            VStack {
                Text("SwiftUI")
                Text("Layout")
            }
            Spacer()
            Image(systemName: "star")
        }
    }
}

Using composition to form our content view, rather than having it contain all of our layout code:

struct ContentView: View {
    var body: some View {
        VStack {
            TopView()
            Spacer()
        }.padding()
    }
}

Adding a new layer to our view hierarchy using a ZStack:

struct ContentView: View {
    var body: some View {
        ZStack(alignment: .bottomTrailing) {
            VStack {
                TopView()
                Spacer()
            }
            Text("A new layer")
        }.padding()
    }
}