TechnologiesSwiftUI

RotateGesture3D struct

iOSmacOStvOSwatchOSvisionOS✓ renders

A gesture that recognizes 3D rotation motion and tracks the angle and axis

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.

  1. 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.

  2. Read the orientation from the gesture value

    As the gesture updates, it reports a value whose rotation property is a Rotation3D — a quaternion-backed orientation describing the axis and amount of turn. In the example, value.rotation is the live spatial orientation the recognizer has accumulated since the drag began.

  3. Respond to updates with onChanged(_:)

    The onChanged modifier 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 assigns value.rotation into the @State property rotation, so the bound state follows the user's motion frame by frame.

  4. 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 rotation to .rotation3DEffect(rotation) applies the recognized orientation to the Text view, closing the loop so the surface visibly turns under the user's finger.

Try it — Replace the body of the 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.

RotateGesture3D.swift
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()
    }
}
Live preview
Drag to rotate in 3D
Drag to rotate in 3D
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →