TechnologiesSwiftUI

Manipulable enum

iOSmacOStvOSwatchOSvisionOS✓ renders

A namespace for various manipulable related types.

How it works

Manipulable describes how a view participates in direct, gesture-driven manipulation — letting people grab, move, rotate, and scale a piece of content with their hands or a pointer. You opt a view into this behavior with the manipulable() family of modifiers, which install the combined move/rotate/scale gesture set with sensible defaults so you don't wire up each spatial gesture by hand. Reach for it when you want content to feel like a physical object the user can pick up and reposition, most commonly with 3D models, while still letting the system manage hit-testing, inertia, and the snap-back to the resting state.

  1. Make a view manipulable with manipulable()

    Calling .manipulable() on a view turns it into a target for the unified manipulation gesture, enabling all available operations — translation, rotation, and scale — at once. In the example, the modifier is applied to the styled Image(systemName: "photo") so that this single view becomes the thing the user can grab; the rest of the chain (resizable(), scaledToFit(), frame, foregroundStyle) only prepares its appearance before manipulation is attached.

  2. Attach it where the content is fully laid out

    Order matters in a modifier chain: manipulable() should sit after the modifiers that establish the view's size and shape, because it manipulates whatever it wraps. Here it follows .frame(width: 120, height: 120) and .foregroundStyle(.blue), so the 120-point square is the region the gesture acts on, and the later .padding() simply reserves room around that manipulable region.

  3. Rely on the default return-to-rest behavior

    By default a manipulable view tracks the active gesture and then animates back to its original transform when the interaction ends, so the layout you authored is never permanently disturbed. The bare .manipulable() call in the example takes this default path — the image springs back to its starting position and scale after each drag, rotate, or pinch.

  4. Restrict the gesture set or track state with the configured forms

    When you need finer control, the configured initializers let you narrow which operations are allowed and observe the result instead of accepting the all-on default. manipulable(using:) takes a manipulation configuration so you can permit, say, only rotation and translation, while manipulable(transform:) binds the live transform so you can retain the position where the user left the object rather than snapping back.

Try it — Bind a transform by switching the bare .manipulable() to .manipulable(transform: $transform) (with a @State var transform) so the photo image keeps the position and scale you leave it in instead of springing back to the 120×120 frame.

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.

Manipulable.swift
struct ManipulableDemo: View {
    var body: some View {
        Image(systemName: "photo")
            .resizable()
            .scaledToFit()
            .frame(width: 120, height: 120)
            .foregroundStyle(.blue)
            .manipulable()
            .padding()
    }
}
Live preview
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →