fix(mobile): stop horizontal recognizers from hijacking diagonal vertical scrolls - #14601
Merged
Merged
Conversation
…ical scrolls Three full-screen horizontal recognizers competed with list scrolling, so a vertical scroll with some sideways drift either did nothing or peeked a screen/drawer and snapped back: - Nested screens: react-native-screens' RNSPanGestureRecognizer (in use since #14205) has no direction test. Commit the patch that requires a committed horizontal drag (>= 5pt toward dismissal, >= 2x the cross-axis travel). Native change: ships with the next binary, not OTA. - Root tabs: the drawer navigator's pan spanned the full screen with fixed 5pt thresholds. Keep it to a 40pt edge and open from mid-screen with a new angle-gated pan (useOpenDrawerGesture) around each tab's stack. - Feed: the For You drawer pan had no failOffsetY, so 20pt of rightward drift anywhere in a long vertical drag opened the drawer. It now uses the shared angle-gated gesture. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Shorten the drawer/swipe-back comments and fix the Feed comment that still described the drawer's swipe edge as full screen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…croll-hijack-wt # Conflicts: # packages/mobile/src/screens/app-screen/AppTabScreen.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Vertical scrolls with some sideways drift either do nothing or peek a screen/drawer and snap back. Most noticeable on Weekly Rotation, but it affects every nested screen and the root tabs. Three full-screen horizontal recognizers compete with the list's scroll:
animation: 'simple_push'+customAnimationOnGesture), react-native-screens uses its ownRNSPanGestureRecognizerfor full-screen swipe-back. UpstreamgestureRecognizerShouldBegin:has no direction test, and once it begins it refuses to run alongside the scroll view's pan. A drag whose first ~10pt has any rightward component gets claimed as a back gesture. Before Fix mobile drawer and screen navigation #14205 iOS 26 used Apple'sinteractiveContentPopGestureRecognizer, which yields to scroll views — that's the "it used to work" state.swipeEdgeWidth: SCREEN_WIDTH) with hardcoded 5pt/5pt thresholds, so it won any touch that moved sideways first.failOffsetY, so 20pt of rightward drift anywhere in a long vertical drag opened the drawer.Changes
patches/react-native-screens+4.18.0.patch(native — needs an App Store release, not OTA):RNSPanGestureRecognizermay only begin on a committed horizontal drag — ≥5pt toward dismissal and ≥2× the cross-axis travel — evaluated once at the pan's activation threshold. Clean horizontal swipes still pop; anything diagonal stays with the scroll view.useOpenDrawerGesture(OTA-able): one direction-locked rightward pan (activeOffsetX 20,failOffsetY ±12) that opens the left drawer from mid-screen. Used by Feed (replacing its inline pan) and wrapped around every tab's stack inAppTabScreen, gated to root + focused + not-now-playing.AppDrawerScreen(OTA-able): the navigator's own swipe is kept to a 40pt left edge; swipe-to-close is unaffected (swipeEdgeWidthonly applies while closed).Verification (iOS simulator, Release builds, iPhone 17 Pro / iOS 26.5)
Reproduced with a synthetic "thumb-arc" drag on the Weekly Rotation page — 16ms samples starting ~15° from horizontal for the first ~13pt, then straightening to vertical — starting on a loaded tile:
Also on this branch: Feed Latest ⇄ For You paging, mid-screen drawer open on For You and Trending, drawer swipe-close, Track back-swipe, and diagonal scrolls on Feed/Trending/Track all behave.
Fast drags never show the bug on either build (both recognizers cross their thresholds in one event and the scroll view wins the tie); it's the slow curved start that gets claimed.
Notes
react_native_assert(attempts < 1024)inShadowTree::commit(via Reanimated's mount hook) when touching tiles — unrelated to this change, but it makes Debug useless for testing this; use Release.post_installbump in the Podfile and will come separately.Podfile.lockdrift frompod installis intentionally not included.🤖 Generated with Claude Code