0

I want to display a View in the top 1/3 of the screen. In order to do so, I manipulate it as so:

var body: some View {
 VStack{
  Spacer()
  Text("I like chipotle")
  Spacer()
  Spacer()
 }
}

While that works for smaller examples, I wonder if there is a more declarative way to do this so if I for example want to put a view in the top 1/6 of a screen? I think about flex box where you can set the flex value of specific children to make them take up different percentages.

joshpetit
  • 677
  • 6
  • 17

2 Answers2

1

Maybe you mean something like this:

struct ContentView: View {

    let partOfScreen: CGFloat = 1/3

    var body: some View {
        GeometryReader { geo in
            VStack(spacing: 0) {
                Text("I like chipotle")
                    .padding(.top, geo.size.height * partOfScreen)
                Spacer(minLength: 0)
            }
        }
    }
}

You can add .ignoresSafeArea(.all) on GeometryReader if the entire screen area is needed

Anastasiia
  • 114
  • 5
  • No need for the `Spacer()` or even the `VStack`. Also adding padding does not arrange it in the exact center of the 1/3 of the top area. You may want to use frame instead – Mojtaba Hosseini Jun 16 '23 at 11:37
  • Yes, my mistake, GeometryReader puts the inner content to the top, Spacer is not really needed – Anastasiia Jun 16 '23 at 12:05
  • @MojtabaHosseini I didn’t really understand how frame would help here, can you explain? To really center the content, I would determine size of Text view something like this: https://stackoverflow.com/questions/64452647/how-we-can-get-and-read-size-of-a-text-with-geometryreader-in-swiftui and subtract half of it in the padding – Anastasiia Jun 16 '23 at 12:17
  • Subtraction will work, but why don't you use the `.center` aligned frame (which is the default alignment)? the a look [here](https://stackoverflow.com/a/76490184/5623035) – Mojtaba Hosseini Jun 16 '23 at 12:25
  • Why is it necessary to make frame of Text view so big? By placing it between other views or a view below it we probably won't get the result that we expect – Anastasiia Jun 16 '23 at 12:57
  • As the OP says: `I want to display a View in the top 1/3 of the screen`. If the need is different like you say, you can make a container around them and frame that instead. – Mojtaba Hosseini Jun 16 '23 at 13:02
0

No need for any Spacer You can directly assign the size to a view relative to its parent using the GeometryReader:

GeometryReader { proxy in
    Text("I like Chipotle")
        .frame(height: proxy.size.height/3.rounded())
    }
}

Quick Tip

Always try to round position and size values. Otherwise, it will heavily impact the render engine to render fractional pixels and you may experience lags and drop frames.

Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278