Make a VStack fill the width of the screen in SwiftUI Make a VStack fill the width of the screen in SwiftUI ios ios

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.


An alternative stacking arrangement which works and is perhaps a bit more intuitive is the following:

struct ContentView: View {    var body: some View {        HStack() {            VStack(alignment: .leading) {                Text("Hello World")                    .font(.title)                Text("Another")                    .font(.body)                Spacer()            }            Spacer()        }.background(Color.red)    }}

The content can also easily be re-positioned by removing the Spacer()'s if necessary.

adding/removing Spacers to change position


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 Spacers to force alignment

You can embed your VStack inside a full size HStack and use trailing and bottom Spacers 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: