TechnologiesSwiftUI

ManipulationUsingGestureStateModifier struct

iOSmacOStvOSwatchOSvisionOS✓ renders

How it works

ManipulationUsingGestureStateModifier is the view modifier SwiftUI applies when you drive a manipulation gesture through an externally owned GestureState rather than letting the gesture manage its own transient value. It connects a 3D manipulation interaction — the combined drag, rotate, and scale gesture used to move entities in space — to a property you declare in your view, so the live transform of the manipulation is published back to your layout while the gesture is in flight. Reach for it when you need to observe or react to an in-progress manipulation, for example to mirror an entity's pose in your interface or to constrain its movement, instead of only receiving the final committed value when the gesture ends.

  1. Declare the manipulation state with @GestureState

    The modifier reads from a @GestureState property whose value is reset automatically when the gesture finishes. You define this state alongside the rest of your view's stored properties, the same place the demo declares the standard view body before composing its VStack of labels.

  2. Attach the manipulation gesture and bind its state

    You apply the manipulation gesture to the target view and route its updating transform into your @GestureState binding; SwiftUI inserts ManipulationUsingGestureStateModifier to wire that connection. The interaction it represents is the move, rotate, and scale combination summarized by the Move · Rotate · Scale overlay in the example.

  3. Observe the live transform during the gesture

    While the user manipulates the entity, the bound state is updated continuously, letting your view reflect the in-progress pose rather than waiting for completion. This is the behavior the demo points at with the caption Drag, rotate, and scale entities with manipulationGestureState.

  4. Let the state reset on completion

    Because the value lives in @GestureState, SwiftUI restores it to its initial value when the manipulation ends, so any UI driven from it — such as the placeholder cube.transparent symbol standing in for the manipulated entity — returns to rest without manual cleanup.

Try it — Change the overlay Text("Move · Rotate · Scale") to read just "Rotate" and pair the demo with a manipulation gesture restricted to rotation, so the bound @GestureState reports only orientation changes while the interaction is active.

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.

ManipulationUsingGestureStateModifier.swift
struct ManipulationUsingGestureStateModifierDemo: View {
    var body: some View {
        VStack(spacing: 12) {
            Image(systemName: "cube.transparent")
                .font(.system(size: 60))
                .foregroundStyle(.tint)
            Text("3D Manipulation")
                .font(.headline)
            Text("Drag, rotate, and scale entities with manipulationGestureState")
                .font(.caption)
                .foregroundStyle(.secondary)
                .multilineTextAlignment(.center)
            RoundedRectangle(cornerRadius: 12)
                .fill(.tint.opacity(0.15))
                .frame(height: 80)
                .overlay {
                    Text("Move · Rotate · Scale")
                        .font(.subheadline.weight(.medium))
                }
        }
        .padding()
    }
}
Live preview
3D Manipulation Drag, rotate, and scale entities with manipulationGestureState Move · Rotate · Scale
3D Manipulation Drag, rotate, and scale entities with manipulationGestureState Move · Rotate · Scale
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →