TechnologiesSwiftUIImmersive Spaces and visionOS

GeometryProxyCoordinateSpace3D struct

iOSmacOStvOSwatchOSvisionOS✓ renders

A representation of a `GeometryProxy3D` which can be used for

How it works

A GeometryProxyCoordinateSpace3D gives you read access to a view's 3D geometry — its size, bounds, and position — measured within a particular coordinate space. In visionOS and other depth-aware contexts, a two-dimensional proxy isn't enough: views occupy volume, and you often need to know a view's extent along the z-axis or convert points and rectangles between named 3D coordinate spaces. Reach for this proxy when you're laying out content in an immersive space, anchoring entities, or computing 3D offsets that must stay consistent as the surrounding layout changes. You don't construct it yourself; SwiftUI hands one to you inside a geometry-reading container so your layout math can react to the actual measured geometry.

  1. Receive the proxy from GeometryReader3D

    The proxy is delivered to you, not created. A 3D geometry reader calls your closure with a fresh proxy each time the layout resolves, so the values always reflect the current geometry. In the example, GeometryReader3D { proxy in ... } binds the parameter proxy, and everything inside the closure can query it.

  2. Read the three-dimensional size

    Asking the proxy for its size returns a 3D size value with width, height, and depth, unlike a 2D proxy that reports only width and height. The depth component is what makes this proxy distinct — it tells you how far the view extends along the z-axis. The example reads proxy.size once and then pulls size.width, size.height, and size.depth to display all three dimensions.

  3. Drive layout from the measured geometry

    Because the proxy reflects real measured values, you use it to compute frames, offsets, and positions for child content rather than guessing fixed numbers. Here the measured dimensions feed a Text view that prints them, but in practice you'd route proxy.size into modifiers like offset or rotation so content scales with its actual volume.

  4. Convert points and bounds across coordinate spaces

    The proxy can resolve a view's bounds or translate 3D points and rectangles into a named coordinate space, which keeps positions stable even as ancestors move or resize. This conversion ability is the reason the type carries "CoordinateSpace" in its name: it ties the geometry it reports to a specific reference frame so your computed positions are unambiguous.

  5. Constrain the container that's being measured

    The proxy measures whatever space the reader is given, so the surrounding frame defines what it reports. Applying .frame(width: 240, height: 80) to the GeometryReader3D bounds the region, and the proxy's size then reflects that allotted geometry; change the frame and the values the proxy hands back change with it.

Try it — Change .frame(width: 240, height: 80) to .frame(width: 240, height: 80, alignment: .center) won't move the numbers, so instead try wrapping the reader in .frame(depth: 120) and watch Int(size.depth) report a non-zero z-extent.

Example & preview

Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.

GeometryProxyCoordinateSpace3D.swift
struct GeometryProxyCoordinateSpace3DDemo: View {
    var body: some View {
        GeometryReader3D { proxy in
            let size = proxy.size
            Text("3D space: \(Int(size.width)) x \(Int(size.height)) x \(Int(size.depth))")
                .font(.headline)
                .padding()
        }
        .frame(width: 240, height: 80)
        .padding()
    }
}
Live preview
3D space: {Int(size.width)} x {Int(size.height)} x {Int(size.depth)}
3D space: {Int(size.width)} x {Int(size.height)} x {Int(size.depth)}
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →