Chr0mePl8edSt0vePipe
Chr0mePl8edSt0vePipe

Reputation: 15

Questioning the dynamicity of Spacers in SwiftUI

I have heard from multiple places that spacers are meant to be dynamic/relative to different screen sizes. I have been using them as an important piece to my layout but they have let me down. Can someone show me if I'm using them incorrectly? Here is an example of a rectangle with an HStack of squares across it. Since the rectangle starts out big and I also need to push it down to the screen I use a lot of spacers(which seem unnecessary). I have tried using padding but it doesn't push it down as much as I need. After the code I've provided you'll see two pictures. One is of an iPod touch(7th generation) and the other of an iPhone 12 Pro Max. The layout doesn't match at all across devices. My goal is for both devices to have the layout porportions that the iPod touch has.

ZStack {
        VStack {
            ForEach(1..<38)  { _ in
                Spacer()
            }
            Rectangle()
                .fill(Color.blue)
        }
        VStack {
            Spacer()
            Spacer()

            HStack {
                Rectangle()
                    .scaledToFit()
                Rectangle()
                    .scaledToFit()
                Rectangle()
                    .scaledToFit()
                Rectangle()
                    .scaledToFit()
                Rectangle()
                    .scaledToFit()
            }

            Spacer()
        }
    }

iPod touch Iphone 12 Pro Max

Upvotes: 0

Views: 1384

Answers (2)

Thai D. V.
Thai D. V.

Reputation: 598

Your question isn't exactly clear what you want the layout to be like. So this code is based on what I speculate about your question, I don't really understand it.

import SwiftUI

struct LayoutView: View {
  var body: some View {
    ZStack {
      VStack {
        Rectangle().fill(Color.white)
        ZStack {
          Rectangle().fill(Color.blue)
          VStack {
            HStack {
              Rectangle().scaledToFit()
              Rectangle().scaledToFit()
              Rectangle().scaledToFit()
              Rectangle().scaledToFit()
              Rectangle().scaledToFit()
            }
            .offset(x: 0, y: 50)
            Spacer()
          }
        }
      }
    }
  }
}

struct LayoutView_Previews: PreviewProvider {
  static var previews: some View {
    LayoutView()
      .previewDevice(.some(.init(rawValue: "iPhone 12 Pro Max")))
    LayoutView()
      .previewDevice(.some(.init(rawValue: "iPod touch (7th generation)")))
  }
}

Upvotes: 1

andykkt
andykkt

Reputation: 1706

You shouldn't need multiple Spacer()

GeometryReader { geometry in
    VStack {
        Spacer()
        
        VStack {
            HStack {
                ForEach(0..<5) {_ in
                    Rectangle()
                        .scaledToFit()
                }
            }
            .padding(.vertical)
            
            Spacer()
        }
        .background(Color.blue)
        .frame(height: geometry.size.height * 0.4)
    }
}

Is this what you are trying to achieve? If you know the size of the view with blue background which I made it as relative to 40% of screen height for now and then Spacer() will fill up the rest of the screen with space.

Upvotes: 1

Related Questions