Search code examples
swiftswiftui

Use available space under centered view


I've tried VStacks and Spacers. GeometryReaders seem really overkill and I wasn't able to figure it out with AlignmentGuides.

I want to keep my blue square content dead center in the middle, and put a menu underneath in the remaining space. Everything I do pushes the blue square up. Whats the best way to achieve this layout?

import SwiftUI

struct Test: View {
  @StateObject private var gameState = GameState()
  
  var body: some View {
    // Blue Square
    VStack {
      Rectangle()
        .fill(Color.blue)
        .aspectRatio(1, contentMode: .fit)
        .frame(maxWidth: .infinity)
      .ignoresSafeArea(.all)
    }
  }
}

#Preview {
  Test()
}

iphone with blue square


Solution

  • All you need to do is to find some view that naturally expands to fill space, and put them before and after the blue content. Adding these will not change the position of the blue content because the two "greedy" views will take up the same space.

    Then, you can put your buttons as an overlay on the second "greedy" view.

    Colors and Shapes are "greedy", so here I used Color.clear for the top of the blue content, and a stroked Rectangle as the bottom of the blue content.

    VStack {
        Color.clear
        Rectangle()
            .fill(Color.blue)
            .aspectRatio(1, contentMode: .fill)
            .frame(maxWidth: .infinity)
            .ignoresSafeArea(.all)
        Rectangle().stroke(.red, lineWidth: 10)
            .overlay {
                VStack {
                    Button("Button 1") {}
                    Button("Button 2") {}
                }
            }
    }
    

    Output:

    enter image description here