How to align objects in a VStack - SwiftUI
#8 - Some examples on how to align objects in a VStack
Hello and welcome back to Learning SwiftUI.
This is issue number 8 and today we will be covering how to align objects in a VStack. This is something I usually get annoyed with so I thought it was time to check it out. I will present two alignment solutions at the end.
There will be no video presented in this post as we will go through how to align objects. However, there will be lots of pictures.Â
Let’s get started with a first example, here we have three different objects aligned in VStack.
struct VStackView: View {
var body: some View {
VStack {
Text("Hello")
.font(.largeTitle)
.foregroundColor(.blue)
Rectangle()
.foregroundColor(.green)
.frame(width: 200, height: 100)
Circle()
.foregroundColor(.red)
.frame(width: 100)
}
}
}
As intended, the objects align vertically as we have them wrapped in a VStack (vertical stack). The total frame of the VStack will be the same as the space the objects will take up. This will be more evident if we add a background, so let’s do that next.
struct VStackView: View {
var body: some View {
VStack {
Text("Hello")
.font(.largeTitle)
.foregroundColor(.blue)
Rectangle()
.foregroundColor(.green)
.frame(width: 200, height: 100)
Circle()
.foregroundColor(.red)
.frame(width: 100)
}
.background(.gray.opacity(0.5))
}
}
As you can see in the picture above, the background will fill with gray color to the outermost areas of our objects within the VStack. We can adjust the frame of the VStack with the frame modifier. Let’s also add an alignment to the VStack to the leading side and an issue will appear.
struct VStackView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Hello")
.font(.largeTitle)
.foregroundColor(.blue)
Rectangle()
.foregroundColor(.green)
.frame(width: 200, height: 100)
Circle()
.foregroundColor(.red)
.frame(width: 100)
}
.frame(maxWidth: .infinity)
.background(.gray.opacity(0.5))
}
}
Want to learn more about SwiftUI animations? Now with a 50% discount. Click the link below.
I created a book for anyone new to SwiftUI that wants to develop their SwiftUI animation skills. The book cover the basics and more advance techniques to animating objects and views in SwiftUI. You can check it out by clicking the link below:
50% Discount: Learning SwiftUI Animations - The Beginner Roadtrip
Two minor examples from the book:
As intended, when we add an infinity for maxWidth, the background width is pushed out. However, the alignment to the leading side does not follow. As you can see in the picture, the objects only align to the leading side of each other. But they do not consider the frame that we set to VStack. I thought that they would move the edge of the screen on the leading side (left). My initial thought was that I can solve this by adding an infinity width to the text view. Like this:
struct VStackView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Hello")
.frame(maxWidth: .infinity)
.font(.largeTitle)
.foregroundColor(.blue)
Rectangle()
.foregroundColor(.green)
.frame(width: 200, height: 100)
Circle()
.foregroundColor(.red)
.frame(width: 100)
}
.background(.gray.opacity(0.5))
}
}
As you now can see, this partly solves our problem. The rectangle and circle views now move out to the edge of the left side of the screen, but the text view stays in the middle. If you want all your objects to align to the leading side of the screen, there are two different ways you can solve this.
Example 1:
The first example is quite easy, all you need to do is add an alignment to the frame and voila! All objects will now align to the left.
struct VStackView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Hello")
.frame(maxWidth: .infinity, alignment: .leading)
.font(.largeTitle)
.foregroundColor(.blue)
Rectangle()
.foregroundColor(.green)
.frame(width: 200, height: 100)
Circle()
.foregroundColor(.red)
.frame(width: 100)
}
.background(.gray.opacity(0.5))
}
}
Example 2:
In this example we will use an HStack and a spacer instead to push out our VStack view.
struct VStackView: View {
var body: some View {
VStack(alignment: .leading) {
HStack {
Spacer() // This spacer pushes the HStack to take up all available space horizontally
}
Text("Hello")
.font(.largeTitle)
.foregroundColor(.blue)
Rectangle()
.foregroundColor(.green)
.frame(width: 200, height: 100)
Circle()
.foregroundColor(.red)
.frame(width: 100)
}
.background(.gray.opacity(0.5))
}
}
There you have it, two different ways to solve how to align all objects to the left side of the screen. If you want them to align to the other side instead, all you have to do is to change VStack(alignment: .leading) to VStack(alignment: .trailing).
That was it for this week's issue. What did you think? Leave a comment or hit me up on Twitter.Â
/Mr SwiftUI