Make a VStack fill the width of the screen in SwiftUI
Try using the .frame
modifier with the following options:
.frame(
minWidth: 0,
maxWidth: .infinity,
minHeight: 0,
maxHeight: .infinity,
alignment: .topLeading
)
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Hello World")
.font(.title)
Text("Another")
.font(.body)
Spacer()
}
.frame(
minWidth: 0,
maxWidth: .infinity,
minHeight: 0,
maxHeight: .infinity,
alignment: .topLeading
)
.background(Color.red)
}
}
This is described as being a flexible frame (see the documentation), which will stretch to fill the whole screen, and when it has extra space it will center its contents inside of it.
With Swift 5.2 and iOS 13.4, according to your needs, you can use one of the following examples to align your VStack
with top leading constraints and a full size frame.
Note that the code snippets below all result in the same display, but do not guarantee the effective frame of the VStack
nor the number of View
elements that might appear while debugging the view hierarchy.
1. Using frame(minWidth:idealWidth:maxWidth:minHeight:idealHeight:maxHeight:alignment:)
method
The simplest approach is to set the frame of your VStack
with maximum width and height and also pass the required alignment in frame(minWidth:idealWidth:maxWidth:minHeight:idealHeight:maxHeight:alignment:)
:
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Title")
.font(.title)
Text("Content")
.font(.body)
}
.frame(
maxWidth: .infinity,
maxHeight: .infinity,
alignment: .topLeading
)
.background(Color.red)
}
}
2. Using Spacer
s to force alignment
You can embed your VStack
inside a full size HStack
and use trailing and bottom Spacer
s to force your VStack
top leading alignment:
struct ContentView: View {
var body: some View {
HStack {
VStack(alignment: .leading) {
Text("Title")
.font(.title)
Text("Content")
.font(.body)
Spacer() // VStack bottom spacer
}
Spacer() // HStack trailing spacer
}
.frame(
maxWidth: .infinity,
maxHeight: .infinity
)
.background(Color.red)
}
}
3. Using a ZStack
and a full size background View
This example shows how to embed your VStack
inside a ZStack
that has a top leading alignment. Note how the Color
view is used to set maximum width and height:
struct ContentView: View {
var body: some View {
ZStack(alignment: .topLeading) {
Color.red
.frame(maxWidth: .infinity, maxHeight: .infinity)
VStack(alignment: .leading) {
Text("Title")
.font(.title)
Text("Content")
.font(.body)
}
}
}
}
4. Using GeometryReader
GeometryReader
has the following declaration:
A container view that defines its content as a function of its own size and coordinate space. [...] This view returns a flexible preferred size to its parent layout.
The code snippet below shows how to use GeometryReader
to align your VStack
with top leading constraints and a full size frame:
struct ContentView : View {
var body: some View {
GeometryReader { geometryProxy in
VStack(alignment: .leading) {
Text("Title")
.font(.title)
Text("Content")
.font(.body)
}
.frame(
width: geometryProxy.size.width,
height: geometryProxy.size.height,
alignment: .topLeading
)
}
.background(Color.red)
}
}
5. Using overlay(_:alignment:)
method
If you want to align your VStack
with top leading constraints on top of an existing full size View
, you can use overlay(_:alignment:)
method:
struct ContentView: View {
var body: some View {
Color.red
.frame(
maxWidth: .infinity,
maxHeight: .infinity
)
.overlay(
VStack(alignment: .leading) {
Text("Title")
.font(.title)
Text("Content")
.font(.body)
},
alignment: .topLeading
)
}
}
Display: