can I get the position of a View after layout in SwiftUI?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
SwiftUI does not expose a direct “give me this view’s final frame” API in the same imperative style as UIKit. Instead, layout information is read through GeometryReader, coordinate spaces, and preference keys after SwiftUI has performed layout. The practical answer is yes, you can get a view’s position, but you must do it in a SwiftUI-native way.
Use GeometryReader to Read Frame Information
GeometryReader lets you inspect a view’s size and frame in a chosen coordinate space. The most common approach is attaching it in the background of the target view so it does not disturb layout.
Using Color.clear avoids rendering visible content while still giving access to the geometry proxy.
That background pattern is important because it lets you measure the view that SwiftUI already laid out, rather than asking a geometry container to propose a new size and change the result you were trying to inspect.
Understand Coordinate Spaces
The same view can have different reported positions depending on which coordinate space you ask for.
Choices include:
- '
.localfor the view’s own local coordinate space.' - '
.globalfor the screen-level coordinate system.' - '
.named(...)for a custom coordinate space you define.'
Named spaces are often the most useful for parent-child layout relationships.
This is more stable than relying on .global when the view is inside scroll views or nested containers.
Use Preference Keys for Reusable Position Reporting
If the parent view needs a child’s position reactively, preference keys are the clean SwiftUI pattern.
This is the pattern to use when layout changes over time and the parent needs updates.
Avoid Disturbing Layout While Measuring
A common mistake is wrapping the target view itself in GeometryReader, which often changes layout because the reader expands to available space. Measuring in .background or .overlay is usually safer.
That distinction matters a lot in stacks, lists, and scroll containers where the parent’s size proposal strongly affects child layout.
Reading Position in Scroll Views
Inside a ScrollView, global coordinates change as the user scrolls. If you need scroll-relative position, use a named coordinate space on the scroll container and measure in that space rather than .global.
This keeps the values meaningful for visibility logic, sticky headers, or scroll-triggered effects.
It also makes the code easier to reason about later because the reported frame stays tied to the container you actually care about, not to the whole screen.
When UIKit Bridging Is Still Useful
If you need highly imperative frame observation or integration with existing UIKit code, a UIViewRepresentable bridge can sometimes be justified. But for most SwiftUI layout tasks, geometry plus preferences is the more idiomatic and maintainable route.
The goal should be to keep layout observation declarative unless you have a strong integration reason not to.
Common Pitfalls
- Using
GeometryReaderas a wrapper and accidentally changing layout. - Reading
.globalcoordinates when a local or named space would be more stable. - Expecting the frame value to be valid before SwiftUI has completed layout.
- Storing geometry in a way that creates unnecessary update loops.
- Using UIKit-style layout assumptions in purely SwiftUI view hierarchies.
Summary
- You can read a SwiftUI view’s position after layout, but the idiomatic tools are
GeometryReaderand preference keys. - Measuring in
backgroundoroverlayis usually safer than wrapping the whole view. - Choose the right coordinate space for the question you are trying to answer.
- Use preference keys when parent views need child layout information reactively.
- Keep the solution declarative unless UIKit interop is truly necessary.

