diff --git a/Sources/SwipeActions.swift b/Sources/SwipeActions.swift index 60eb846..173ff6c 100644 --- a/Sources/SwipeActions.swift +++ b/Sources/SwipeActions.swift @@ -176,6 +176,9 @@ public struct SwipeOptions { /// Values for controlling the trigger animation. var offsetTriggerAnimationStiffness = Double(160), offsetTriggerAnimationDamping = Double(70) + + /// The priority for the swipe view drag gesture + var swipeViewDragGesturePriority: GesturePriority = .high } // MARK: - Environment @@ -439,7 +442,7 @@ public struct SwipeView: View where Labe // MARK: - Add gestures - .highPriorityGesture( /// Add the drag gesture. + .gesture( /// Add the drag gesture. DragGesture(minimumDistance: options.swipeMinimumDistance) .updating($currentlyDragging) { value, state, transaction in state = true @@ -447,7 +450,8 @@ public struct SwipeView: View where Labe .onChanged(onChanged) .onEnded(onEnded) .updatingVelocity($velocity), - including: options.swipeEnabled ? .all : .subviews /// Enable/disable swiping here. + including: options.swipeEnabled ? .all : .subviews, /// Enable/disable swiping here. + priority: options.swipeViewDragGesturePriority ) .onChange(of: currentlyDragging) { currentlyDragging in /// Detect gesture cancellations. if !currentlyDragging, let latestDragGestureValueBackup { @@ -1256,6 +1260,13 @@ public extension SwipeView { view.options.offsetTriggerAnimationDamping = damping return view } + + /// The priority of the swipe view's drag gesture + func swipeDragGesturePriority(_ value: GesturePriority) -> SwipeView { + var view = self + view.options.swipeViewDragGesturePriority = value + return view + } } /// Modifier for a clipped delete transition effect. @@ -1424,3 +1435,34 @@ struct AllowSwipeToTriggerKey: PreferenceKey { static var defaultValue: Bool? = nil static func reduce(value: inout Bool?, nextValue: () -> Bool?) { value = nextValue() } } + + +// MARK: Configurable gesture priority + +/// The relative priority of a SwiftUI gesture +public enum GesturePriority { + case high + case normal +} + +/// A view modifier that allows a gesture to have a configurable priority +fileprivate struct ConfigurableGesturePriority: ViewModifier { + let gesture: any Gesture + let mask: GestureMask + let priority: GesturePriority + + func body(content: Content) -> some View { + switch priority { + case .high: + AnyView(content.highPriorityGesture(gesture, including: mask)) + case .normal: + AnyView(content.gesture(gesture, including: mask)) + } + } +} + +extension View { + func gesture(_ gesture: some Gesture, including mask: GestureMask, priority: GesturePriority) -> some View { + modifier(ConfigurableGesturePriority(gesture: gesture, mask: mask, priority: priority)) + } +}