A PanGestureHandler wired to the root view or main screen swallows the iOS edge-swipe-back gesture — users can no longer navigate back and file crash-level bug reports. Globally-scoped swipe handlers also fight with ScrollView momentum, producing frozen scrolls and ghost taps. Apple's HIG explicitly reserves edge gestures for the system, and conflicts here are a common rejection reason during App Store review.
High because breaking system navigation gestures strands users on a screen with no visible way out.
Scope every custom gesture to the smallest possible subtree and never attach a pan handler at the screen or NavigationContainer level. Use react-native-gesture-handler's simultaneousHandlers and waitFor to coordinate with scroll gestures:
<PanGestureHandler onGestureEvent={onSwipe} activeOffsetX={[-20, 20]}>
<Animated.View style={animatedStyle}>{/* card only */}</Animated.View>
</PanGestureHandler>
Set activeOffsetX so horizontal swipes on the edge still reach the native navigator.
ID: mobile-ux-patterns.touch-gestures.gesture-conflicts
Severity: high
What to look for: List all custom gesture handlers in the app (PanGestureHandler, SwipeGestureHandler, PinchGestureHandler, etc.). For each, check whether it is scoped to a specific component or applied globally. Check for conflicts with iOS swipe-back, Android back button, and scroll gestures.
Pass criteria: All custom gestures are scoped to specific components (not applied at root or screen level) and do not interfere with at least 3 system gestures: iOS swipe-back navigation, Android back button, and scroll gestures. Report the count even on pass: "Found N custom gesture handlers, all scoped correctly."
Fail criteria: Any custom gesture is globally applied or conflicts with system navigation (e.g., custom pan handler on main screen prevents swipe-back on iOS, swipe handler interferes with scrolling).
Skip (N/A) when: The app uses no custom gestures (only standard buttons and taps) — no react-native-gesture-handler or manual gesture code detected.
Detail on fail: Identify the gesture conflict. Quote the handler component and its scope. Example: "Pan gesture on main screen prevents iOS swipe-back navigation on all screens." or "Custom swipe-to-delete on list items interferes with horizontal scroll in some cases."
Remediation: Use react-native-gesture-handler with proper gesture configuration to avoid conflicts. Scope gestures to specific components and use simultaneous handlers carefully:
import { GestureHandlerRootView, PanGestureHandler } from 'react-native-gesture-handler';
// Scope gesture to specific component, not whole screen
<GestureHandlerRootView>
<PanGestureHandler onGestureEvent={onSwipe}>
<Animated.View style={animatedStyle}>
{/* Swipeable card */}
</Animated.View>
</PanGestureHandler>
</GestureHandlerRootView>
Use simultaneousHandlers or waitFor to coordinate multiple gestures and prevent conflicts with built-in scroll and navigation gestures.