SwiftUI - Global coordinate space is flipped on macOS

Viewed 583

Edit:

It was confirmed to be an Apple bug. It's now fixed on macOS Monterey


It seems to me that reading frames through GeometryReader is broken on macOS.

Apparently when you read a frame in local or named coordinate space, returned frame is in "SwiftUI coordinate space" where the (0,0) point is in the upper-left corner.

However, when you read a frame in a global space, returned frame is in the "native macOS space" where the (0,0) is in the bottom-left corner.

Is this behavior documented anywhere or is it a bug? I'm trying to figure out if I'm missing something here.

My sample code:

struct ContentView: View {
var body: some View {
    ZStack(alignment: .bottom) {
        Color.blue
            .frame(width: 100, height: 150)


        Color.red
            .frame(width: 20, height: 60)
            .background(
                GeometryReader { geo -> Color in
                    let g = geo.frame(in: .global)
                    let s = geo.frame(in: .named("stack"))
                    print("Global: \(g) | Stack: \(s)")

                    return Color.purple
                }
            )
        .padding(.bottom, 5)
    }
    .coordinateSpace(name: "stack")
    .padding(40)
    .background(Color.pink)
}

Output:

Global: (80.0, 45.0, 20.0, 60.0) | Stack: (40.0, 85.0, 20.0, 60.0)

enter image description here

1 Answers

I gotcha. I misread what you wrote. I spent some time going down this rabbit hole, and found no clear answer. No one is talking about local versus global coordinate spaces. As a test on .frame, I modified your GeometryReader like this:

GeometryReader { geo -> Color in
                        let g = geo.frame(in: .global)
                        let gX = g.minX
                        let gY = g.minY
                        let s = geo.frame(in: .named("stack"))
                        print("Global: \(g), minX: \(gX), minY: \(gY) | Stack: \(s)")

and the output ended up being:

Global: (80.0, 45.0, 20.0, 60.0), minX: 80.0, minY: 45.0 | Stack: (40.0, 85.0, 20.0, 60.0)

So, while I can't answer your question as to what Apple intended, clearly the Global coordinate system is rotated, and it is not a bug in .frame switching x for y in a global space. Yet something else that is undocumented.

Related