HStack, VStack and ZStack in SwiftUI

- Andrés Cruz

En español
HStack, VStack and ZStack in SwiftUI

When we create a project in SwiftUI we have a default class called ContentView that of course we can change its name if it's not to your liking but it's not really relevant at the moment... in this file there is a view component, which in the practice has only been a screen of our app, a screen or view for login, registration, a list, etc; you can see some of the emulator images in this post to give you a better idea.

In this component, specifically in the struct that has the same name as the file, ContentView by default, there is a variable called body which defines the body of our view; in it we have to define graphical interface elements, although there is a very important point, and that is that it can ONLY see a root element; for example a text:

struct ContentView: View {
        
    var body: some View {
        Text("Hola")
            .foregroundColor(blue)
    }
} 
Texto en SwiftUI

Now, what happens if we want to place more content, what is it that you will surely want to do in most cases:

struct ContentView: View {
        
    var body: some View {
        Text("Hola")
            .foregroundColor(blue)
        Text("Hola")
            .foregroundColor(blue)
    }
}

You will see that you will not be able to, or it will not work as expected; and this is where the layout components come in.

V,H,Z Stack to stack or place multiple content

These have been the main elements in SwiftUI, which have been the Layout components; They are components or boxes that allow us to group multiple elements for our UI Graphic Interface, they are the famous 3 layout components VStack, HStack, and ZStack.

VStack is a container that allows us to add multiple children, multiple elements stacked vertically.

HStack is a container that allows us to add multiple children, multiple elements stacked horizontally.

Finally we have a ZStack component to place the elements aligning in any of its axes, the interesting thing about this is that we can place or define them in any position, giving immense creativity to our interfaces.

Example of a VStack view

So in summary, with these layout components we can organize multiple content, as much as we need; so if we want to apply texts:

   var body: some View {
        VStack {
            Text("Hola")
                .foregroundColor(.blue)
            Text("Hola")
                .foregroundColor(.red)
            Text("Hola")
                .foregroundColor(.yellow)
        }
    } 
Textos y VStack

And of course we can apply some styles to our content, such as changing its color as we did before or even changing the color of the container element:

     VStack {
            Text("Hola")
                .foregroundColor(.blue)
            Text("Hola")
                .foregroundColor(.red)
            Text("Hola")
                .foregroundColor(.yellow)
        }.background(Color.purple)

Some Padding:

        VStack {
            Text("Hola")
                .foregroundColor(.blue)
            Text("Hola")
                .foregroundColor(.red)
            Text("Hola")
                .foregroundColor(.yellow)
        }.padding().background(Color.purple)

For this it is important to note that you have to apply the padding before the background color, since here in SwiftUI the order of the factors DOES alter the product:

Summary

  • A VStack adds items vertically, with our views or visuals added from top to bottom.
  • Adding Spacer() forces the view to use the maximum amount of vertical space.
  • Adding a Divider() forces the view to use the maximum amount of horizontal space.

By default, the dividing line has no color. To set the color of the divider, we add the .background(Color.black) modifier/function. Elements like background(Color.black), .padding(), and .offests(…) are called ViewModifiers, or simply modifiers. Modifiers can be applied to views or other modifiers, producing variations.

Remember to define the ContentView_Previews to see a preview of the content you are putting together.

struct ContentView: View {
        
    var body: some View {
        VStack {
            Text("Hola")
                .foregroundColor(.blue)
            Text("Hola")
                .foregroundColor(.red)
            Text("Hola")
                .foregroundColor(.yellow)
        }.padding().background(Color.purple)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

And now, we are going to present some more elements that come together; For example, what happens if you want your container, VStack, to occupy the WHOLE screen, that is, to grow in length and width and with this the entire size of the available screen, for that, we have to use the Spacer and Divider elements respectively :

   var body: some View {
        VStack {
            Text("Hola")
                .foregroundColor(.blue)
            Text("Hola")
                .foregroundColor(.red)
            Spacer()
            Divider()
            Text("Hola")
                .foregroundColor(.yellow)
            
        }.padding().background(Color.purple)
    }

Component HStack

Now, if you want to stack horizontally:

    var body: some View {
        HStack {
            Text("Hola")
                .foregroundColor(.blue)
            Text("Hola")
                .foregroundColor(.red)
            Spacer()
            Divider()
            Text("Hola")
                .foregroundColor(.yellow)
            
        }.padding().background(Color.purple)
    } 
Textos, Spacer, Divider

VStack, stack your content vertically, HStack stack your content horizontally

In any case, you can also stack your content vertically, as if it were a row, although in most cases you will want to stack it in a column, you can also apply it vertically, for this, we have to use the VStack; otherwise everything is exactly the same as the HStack.

Component ZStack

ZStack, put your elements anywhere, in many cases, you may want to place elements on top of each other or at least have more control to customize your elements in your interface, and this is what ZStack allows you to do, that with the function of offset, allows you to indicate the position on the Cartesian axis by indicating a parameter for the x and y:

struct ContentView: View {
    
    var body: some View {
        HStack {
            Text("Hola")
                .foregroundColor(.blue)
            Text("Hola")
                .foregroundColor(.red)
            
            ZStack{
                Text("ZStack Texto 1")
                    .padding()
                    .background(Color.green)
                    .opacity(0.8)
                Divider()
                Text("ZStack Texto 2")
                    .padding()
                    .background(Color.green)
                    .offset(x: 80, y: -200)
            }.background(Color.blue)
            
            Spacer()
            Divider()
            Text("Hola")
                .foregroundColor(.yellow)
        }.padding().background(Color.purple)
    }
} 
ZStack

Conclusions

Now with this you have the necessary elements to use to create your first interfaces and start organizing your interfaces as you want. These container elements are essential to build the bases of your app, to indicate the structure in which other elements such as images, texts, text fields, form elements, etc. will be contained.

Andrés Cruz

Develop with Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz In Udemy

I agree to receive announcements of interest about this Blog.