When we create a SwiftUI project in Xcode, we see something like this
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.padding()
}
}
Everything is centered in the middle of the screen by default. Let’s see how to move the elements to other positions.
Vertical Stack
The purpose of this stack is to organize items in a vertical flow. It’s possible to align the elements in the stack to the leading (left), trailing (right), or center (the default) positions. To add spacing between the elements, use the spacing property.
struct ContentView: View {
var body: some View {
VStack(alignment: .leading, spacing: 20) {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.padding()
}
}
How can we push the objects in the VStack to the top of the view? We need to use the Spacer object.
struct ContentView: View {
var body: some View {
VStack(alignment: .leading, spacing: 20) {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
Spacer()
}
.padding()
}
}
The Spacer fills all available space unless a specific size is set for it.
Horizontal Stack
The horizontal stack (HStack) is the counterpart of the vertical stack (VStack).
struct ContentView: View {
var body: some View {
HStack(alignment: .center, spacing: 20) {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.padding()
}
}
The possible alignments are:
- .center
- .top
- .bottom
- .firstTextBaseline
- .lastTextBaseline
Take a look at the text baseline alignment:
struct ContentView: View {
var body: some View {
HStack(alignment: .lastTextBaseline, spacing: 0) {
Color.red.frame(height: 1)
Text("First Text Baseline").font(.title).border(.gray)
Color.red.frame(height: 1)
}
}
}
struct ContentView: View {
var body: some View {
HStack(alignment: .firstTextBaseline, spacing: 0) {
Color.red.frame(height: 1)
Text("First Text Baseline").font(.title).border(.gray)
Color.red.frame(height: 1)
}
}
}
As you can see, the red lines on the left and right of the text are aligned with the text’s first baseline (either the first or last line).
You can also use Spacer within an HStack to move items to the left or right as needed.
Z Stack
The ZStack is like a stack of layers, with items piled on top of each other.
struct ContentView: View {
var body: some View {
ZStack() {
Text("I'm level 0")
.foregroundStyle(Color.white)
.padding(100)
.background(Color.gray)
Text("I'm level 1")
.foregroundStyle(Color.blue)
}
}
}
In this case the text are overlapped:
The item on the background is the first in the ZStack and so on.
In this way the text is not readable, so we can use the .topLeading aligment to move the second on the top left corner:
struct ContentView: View {
var body: some View {
ZStack(alignment: .topLeading) {
Text("I'm level 0")
.foregroundStyle(Color.white)
.padding(100)
.background(Color.gray)
Text("I'm level 1")
.foregroundStyle(Color.blue)
}
}
}
There are fifteen alignments, so try the others.
If you don’t want to use alignment, you can use the offset instead
struct ContentView: View {
var body: some View {
ZStack {
Text("I'm level 0")
.foregroundStyle(Color.white)
.padding(100)
.background(Color.gray)
Text("I'm level 1")
.foregroundStyle(Color.blue)
.offset(x: 0, y: 80)
}
}
}
The X and Y coordinates are relative to the starting position of the first element.
Stacks are powerful elements in SwiftUI.