How it works
Viewpoint3D describes the direction from which a person is looking at a volumetric window in visionOS. Because a volume can be viewed from any side as someone moves around it, SwiftUI hands you a Viewpoint3D value so your content can react to where the viewer actually stands — reorienting labels, swapping faces, or biasing layout toward whoever is watching. Reach for it whenever a volume needs to feel oriented to the person rather than fixed in space, and store the current value in state so the view re-renders as the viewpoint changes.
Hold the current viewpoint in @State
Viewpoint3Dis a value type, so keep the active viewpoint in view state and read it frombody; SwiftUI re-evaluates the view whenever you assign a new one. In the example@State private var viewpoint = Viewpoint3D.frontseeds that storage, and theButtonupdates it withviewpoint = .frontto drive a fresh render.Start from the standard front viewpoint
The type vends
Viewpoint3D.standard, a value that represents being viewed from the front middle — a sensible default before the system reports a real viewer position. The example uses a front-facing value as its baseline, the same rolestandardplays as the neutral starting orientation.Read the snapped direction through squareAzimuth
The
squareAzimuthproperty exposes which side the viewer is on as aSquareAzimuth, snapped to one of four horizontal directions (front, back, left, right). Branching onviewpoint.squareAzimuthlets you pick the content for the face that's currently being looked at, rather than tracking a continuous angle.Compare viewpoints with Equatable
Viewpoint3Dconforms toEquatable, so you can test the stored value with==to decide whether anything actually changed before doing work. This is what makes the example'sviewpoint = .frontassignment meaningful — SwiftUI can compare the old and new values and only refresh when they differ.Receive updates from the volume
In a real volume you don't set
Viewpoint3Dby hand; the system delivers it throughonVolumeViewpointChange(updateStrategy:initial:_:), which calls your closure with the new viewpoint as the viewer moves. The example's button stands in for that callback — the place where an incomingViewpoint3Dwould be written intoviewpointandSendablelets it cross those update boundaries safely.
viewpoint to a left-facing value, then switch the Text("Box") overlay to read off viewpoint.squareAzimuth so the box's label changes as the viewpoint flips between front and left.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 Viewpoint3DDemo: View {
@State private var viewpoint = Viewpoint3D.front
var body: some View {
VStack(spacing: 16) {
Text("3D Viewpoint")
.font(.headline)
RoundedRectangle(cornerRadius: 12)
.fill(.blue.gradient)
.frame(width: 120, height: 120)
.overlay(Text("Box").foregroundStyle(.white))
Button("Look from Front") {
viewpoint = .front
}
.buttonStyle(.borderedProminent)
}
.padding()
}
}