How it works
RotateGesture3D is a gesture that recognizes a three-dimensional rotation as the user drags across a view, producing a Rotation3D value that describes orientation about an arbitrary axis rather than a single angle in the plane. Reach for it when a flat RotateGesture isn't enough — when you want a control or model to tumble freely in space, as in volumetric and spatial interfaces. Like other SwiftUI gestures it's a value type you attach with the gesture(_:) modifier and observe through its action callbacks, letting you bind the live rotation to your view's presentation.
Create the gesture with RotateGesture3D()
The initializer constructs a recognizer that tracks rotation in three dimensions as the drag proceeds. Here
RotateGesture3D()is created inline and handed to the.gesture(...)modifier, which is where the symbol plugs into the view hierarchy and begins receiving touch or pointer input.Read the orientation from the gesture value
As the gesture updates, it reports a value whose
rotationproperty is a Rotation3D — a quaternion-backed orientation describing the axis and amount of turn. In the example,value.rotationis the live spatial orientation the recognizer has accumulated since the drag began.Respond to updates with onChanged(_:)
The
onChangedmodifier registers a closure that runs each time the gesture's value changes, giving you a continuous stream of orientations during the drag. The closure here assignsvalue.rotationinto the@Statepropertyrotation, so the bound state follows the user's motion frame by frame.Drive the view with the captured rotation
Because the gesture's output is ordinary observed state, you can feed it directly into a view modifier. Passing
rotationto.rotation3DEffect(rotation)applies the recognized orientation to theTextview, closing the loop so the surface visibly turns under the user's finger.
onChanged closure with rotation = .identity so the view snaps back upright while you drag, revealing how continuously RotateGesture3D delivers updates.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 RotateGesture3DDemo: View {
@State private var rotation = Rotation3D.identity
var body: some View {
Text("Drag to rotate in 3D")
.font(.headline)
.padding()
.frame(width: 200, height: 200)
.background(.blue.gradient, in: .rect(cornerRadius: 16))
.foregroundStyle(.white)
.rotation3DEffect(rotation)
.gesture(
RotateGesture3D()
.onChanged { value in
rotation = value.rotation
}
)
.padding()
}
}