GeometryReader with child goes beyond the safe area with SwiftUI

118 Views Asked by At

I am new to SwiftUI, and when I tried to render Texts inside a GeometryReader, the content seems overlapping with safeareinsets.top and safeareinsets.bottom. Following is the code that I have been used.

    struct ContentView: View {
    var body: some View {
        GeometryReader { geo in
            HStack {
                Spacer()
                VStack(spacing: 0) {
                    Text("Top")
                        .font(.largeTitle)
                        .foregroundStyle(.black)
                        .frame(height: geo.size.height * 0.5)
                        .background(.red)
                    Text("Bottom")
                        .font(.largeTitle)
                        .foregroundStyle(.black)
                        .frame(height: geo.size.height * 0.5)
                        .background(.red)
                    
                }
                .background(.yellow)
                Spacer()
            }
        }.background(.blue)
    }
}

enter image description here

At the same time, if I used Color component with same height ratio, the Childs are not going beyond the safe area.

struct ContentView: View {
    var body: some View {
        GeometryReader { geo in
            HStack {
                VStack(spacing: 0) {
                    Color(.red)
                        .frame(height: geo.size.height * 0.5)
                    Color(.brown)
                        .frame(height: geo.size.height * 0.5)
                }
                .background(.yellow)
            }
        }.background(.blue)
    }
}

Can anyone please advise?

Screenshots of each cases

1

There are 1 best solutions below

0
On

The background modifier that you are using ignores safe areas by default.

func background<S>(
    _ style: S,
    ignoresSafeAreaEdges edges: Edge.Set = .all // the default ignores all safe areas
) -> some View where S : ShapeStyle

The overload that takes a view builder doesn't do this, so you can use that instead:

.background { Color.red }

Alternatively, pass the empty set to the ignoresSafeAreaEdges parameter.

.background(.red, ignoresSafeAreaEdges: [])