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.
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 parameterproxy, and everything inside the closure can query it.Read the three-dimensional size
Asking the proxy for its
sizereturns a 3D size value withwidth,height, anddepth, unlike a 2D proxy that reports only width and height. Thedepthcomponent is what makes this proxy distinct — it tells you how far the view extends along the z-axis. The example readsproxy.sizeonce and then pullssize.width,size.height, andsize.depthto display all three dimensions.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
Textview that prints them, but in practice you'd routeproxy.sizeinto modifiers like offset or rotation so content scales with its actual volume.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.
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 theGeometryReader3Dbounds the region, and the proxy'ssizethen reflects that allotted geometry; change the frame and the values the proxy hands back change with it.
.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.
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()
}
}