Let's think about this for a moment
VStack arranges its child views vertically (top-to-bottom) — HStack arranges them horizontally (left-to-right). ZStack places child views on top of each other so they overlap (for example, text overlaid on an image). Modifiers are a toolkit for customizing a view's appearance/behavior (padding, frame, background color, onTapGesture) by chaining them together, like `.padding(16).background(Color.blue)`.
Let's connect this to a real-world scenario
Say you're designing a login screen — inside a `VStack` you could arrange a logo (Image), an email TextField, a password TextField, and a login Button vertically — adding `.padding(16)` to the VStack gives you space between the screen edge and the content.
Let's look at it together
struct LoginScreen: View {
var body: some View {
VStack {
Text("Welcome Back")
.font(.title)
Spacer().frame(height: 16)
HStack {
Image(systemName: "envelope")
Text("email@example.com")
}
}
.padding()
}
}You should see an email icon + text laid out as a row underneath the 'Welcome Back' text on the Simulator.Try it in 5 minutes
Expand `LoginScreen` yourself — add two TextFields for email/password plus a Login Button inside the VStack and run it on the Simulator.
A quick word of caution
Overusing `.frame(maxWidth: .infinity)` on deeply nested views can make it hard to predict the actual layout size — it's better to use it only at the root level and give child views specific sizes instead.