SwiftUI GeometryReader: Where am I? - Part 2

Mark Moeykens
Nov 15, 2019


This is part 2 in the GeometryReader Series. Part 1 is here.

Every screen has a coordinate system that starts in the upper left as X: 0, Y: 0.


This is called the global coordinate space.

If you're following along in the free SwiftUI Views book sample, you can see that the geometry reader can find out its own origin (X, Y) within this global coordinate space (or the local coordinate space but this will always be 0,0).

The "origin" of a view is the upper-left point of the view.

You can use multiple geometry readers around views to reveal the origin of views.

The X values are all the same because all of those rounded rectangles are all indented 20 points. The Y values are all different though. The Y value increases as you move down from the top where it starts at zero.

Here is the code for one of the rounded rectangles wrapped in a GeometryReader:
 
GeometryReader { gr in 
    RoundedRectangle(cornerRadius: 20) 
        .fill(Color.pink) 
        .overlay( 
            VStack { 
                Text("X: \(Int(gr.frame(in: .global).origin.x))") 
                Text("Y: \(Int(gr.frame(in: .global).origin.y))") 
        }) 
}.frame(height: 400) 

(I used "gr" for my geometry reader parameter name to keep it short.)

The Origins of These Views Will Change in a ScrollView
As you can see in the gif below, when the first view (red rectangle) scrolls towards the top, the Y value will reach zero. Scrolling past that, the Y value becomes negative.



(Overlaying text is probably my favorite way of debugging geometry reader values.)

This concept of the changing origin while scrolling is something you will be using to create the parallax effect and the sticky header effect.

Further Study

In the SwiftUI Views book under the GeometryReader section, you'll also see some pages talking about "Min Mid Max Coordinates".

Just to let you know, you can use the minY and minX to also get the origin.Y and origin.X values respectively.

// These two values are the same 
Text("X: \(Int(gr.frame(in: .global).origin.x))") 
Text("X: \(Int(gr.frame(in: .global).minX))") 

// These two values are the same 
Text("Y: \(Int(gr.frame(in: .global).origin.y))") 
Text("Y: \(Int(gr.frame(in: .global).minY))") 

(Saves you a few precious keystrokes. 😆)

Summary

Use the geometry reader's frame in the global coordinate space to access the origin. You can also use the frame's minX and minY which will be the same as the origin X and Y values.

Coming up next, I'm going to show you how to create the parallax effect by using the geometry reader. It's easier than you are probably thinking but for me, it was like this big paradigm shift in thinking. 😃 You know, just like SwiftUI was from UIKit.

Continue to Part 3 ->

Free SwiftUI Picture Book


Screenshots for every code example? Yes! Get your FREE SwiftUI picture book here.