Snippets
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
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 })
)
}
}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
SwiftUI Tap, Long Press, and Drag Gestures
Pick the simplest gesture that matches the user's intent, then promote to explicit Gesture values only when you need state or composition.
SwiftUI disabled, redacted, and allowsHitTesting
Represent unavailable, loading, private, and pass-through states with the right interaction and visual modifiers.
SwiftUI Canvas Drawing Context
Use Canvas when a visual is easier to draw than compose from many nested views, such as sparklines, badges, waveforms, and lightweight charts.