TechnologiesSwiftUI

ManipulableTransformBindingModifier struct

iOSmacOStvOSwatchOSvisionOS✓ renders

How it works

ManipulableTransformBindingModifier is the modifier type that backs the manipulable() view modifier, giving a view direct, gesture-driven spatial manipulation. Once applied, the view responds to drag, rotate, and scale interactions as a single composable transform, freeing you from wiring up individual DragGesture, RotationGesture, and MagnificationGesture handlers and reconciling their state by hand. Reach for it when you want a piece of content to feel like a movable, resizable object the user can grab and arrange in space, rather than a fixed element in a layout.

  1. Apply the modifier with manipulable()

    The manipulable() modifier is the entry point: calling it on any view wraps that view in a ManipulableTransformBindingModifier and installs the recognizers that interpret drag, rotation, and scale input. In the example, .manipulable() is attached to the first Text, turning the styled "Drag, rotate, scale me" view into an object the user can move, spin, and resize.

  2. Understand the transform it manages

    ManipulableTransformBindingModifier tracks an accumulated affine transform — translation, rotation, and scale combined — and applies it to the modified view's rendering as gestures change. Because it manages one unified transform, the manipulations on the Text compose naturally: dragging shifts position while a pinch concurrently adjusts scale, with no manual coordinate math on your side.

  3. Layer it after your visual styling

    The modifier transforms whatever view it receives, so order matters: place .manipulable() at the end of the chain to manipulate the fully decorated result. Here it follows .font(.headline), .padding(), .background(.blue.gradient, in: .rect(cornerRadius: 12)), and .foregroundStyle(.white), so the rounded blue card — text and chrome together — moves as one manipulable unit.

  4. Compose it inside ordinary containers

    A manipulable view remains a normal View and participates in layout like any other, so it can sit among siblings in a stack. The manipulated Text lives inside a VStack(spacing: 16) alongside the static "Spatial manipulation" caption, which has no .manipulable() and therefore stays put as a fixed label.

Try it — Add .manipulable() to the second Text("Spatial manipulation") line as well, then drag each card independently to confirm the modifier gives every view it touches its own transform.

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.

ManipulableTransformBindingModifier.swift
struct ManipulableTransformBindingModifierDemo: View {
    var body: some View {
        VStack(spacing: 16) {
            Text("Drag, rotate, scale me")
                .font(.headline)
                .padding()
                .background(.blue.gradient, in: .rect(cornerRadius: 12))
                .foregroundStyle(.white)
                .manipulable()
            Text("Spatial manipulation")
                .font(.caption)
                .foregroundStyle(.secondary)
        }
        .padding()
    }
}
Live preview
Drag, rotate, scale me Spatial manipulation
Drag, rotate, scale me Spatial manipulation
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →