Snippets
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.
5 min readUpdated 2026-06
import SwiftUI
struct DraggableCard: View {
@State private var offset: CGSize = .zero
var body: some View {
RoundedRectangle(cornerRadius: 20)
.fill(.teal.gradient)
.frame(height: 180)
.offset(offset)
.gesture(
DragGesture()
.onChanged { offset = $0.translation }
.onEnded { _ in
withAnimation(.spring()) { offset = .zero }
}
)
}
}Implementation notes
onTapGesture is convenient, but Button remains better for command actions because it carries platform semantics.
DragGesture values include translation and locations, which usually avoids manual coordinate math.
Long-press interactions should have a visible alternative for discoverability.
Checklist
Test inside ScrollView and List because gesture competition changes behavior.
Keep animation reset behavior predictable.
Add accessibility actions for gesture-only features.
Related reference
SwiftUI Gesture Composition and Priority
Combine gestures with simultaneous, sequenced, exclusive, and high-priority relationships when a view needs more than one interaction.
SwiftUI disabled, redacted, and allowsHitTesting
Represent unavailable, loading, private, and pass-through states with the right interaction and visual modifiers.
SwiftUI Overlay, Background, and zIndex
Layer views deliberately with background, overlay, and zIndex while keeping the base layout stable.