SwiftUI.cc
Snippets
GesturesGesturesAdvanced

SwiftUI Gesture Composition and Priority

Combine gestures with simultaneous, sequenced, exclusive, and high-priority relationships when a view needs more than one interaction.

5 min readUpdated 2026-06
Pinch and drag surface
import SwiftUI

struct ZoomableSurface: View {
    @State private var scale = 1.0
    @State private var offset: CGSize = .zero

    var body: some View {
        Image("map-preview")
            .resizable()
            .scaledToFit()
            .scaleEffect(scale)
            .offset(offset)
            .gesture(
                DragGesture().onChanged { offset = $0.translation }
                    .simultaneously(with: MagnificationGesture().onChanged { scale = $0 })
            )
    }
}
Use this when

A canvas, photo, map, or card needs multiple gestures at the same time.

One gesture should win when two interactions could be recognized.

A second gesture should start only after a first gesture succeeds.

Avoid this when

The composition makes the interaction hard to predict.

A built-in control already handles the gesture combination.

Gesture priority is being used to fight parent scroll behavior without a product reason.

Implementation notes

simultaneously allows both gestures to report values, while exclusively chooses the first one that wins.
sequenced gestures are useful for long-press-then-drag interactions.
highPriorityGesture is a blunt but useful tool when child and parent gestures compete.

Checklist

Define which gesture owns cancellation and reset behavior.

Test with one finger, two fingers, trackpad, and VoiceOver when relevant.

Keep state updates small during onChanged callbacks.

Related reference