swiftuivstackswiftui-spacer

SwiftUI - How do I make a VStack containing three Views where one is fixed size and the others fill the space?


I need a "MainView" that is centered on the screen, and a flexible "HeaderView" that takes up the remaining space between the MainView and the top of the screen (see below).

How do I accomplish this in SwiftUI?

enter image description here

Starter code:

struct TestView: View {
    var body: some View {
        ZStack {
            //Center Line
            Divider()
            
            VStack {
                Text("HeaderView")
                    .border(Color.orange, width: 6)
                Text("MainView")
                    .frame(width: 400, height: 200, alignment: .center)
                    .border(Color.red, width: 6)
            }
        }
        
    }
}

Solution

  • VStack {
        // Let the HeaderView expand to whatever is available, in both directions
        Text("HeaderView")
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .border(Color.orange, width: 6)
    
        Text("MainView")
            .frame(maxWidth: .infinity) // Added to allow this view to expand horizontally
            .frame(height: 200) // alignment is not needed here.
            .border(Color.red, width: 6)
    
        // And then add a Spacer() at the end that also has flexible height
        Spacer()
            .frame(maxHeight: .infinity)
    }
    

    Since Main is fixed in height, it will get its requested height first. Then since Header and Spacer are equally prioritized and flexible, they will each get half of what remains, causing Main to be centered vertically.