Description
With a bottom-tab navigator using detachInactiveScreens={false} and screenOptions={{ lazy: false }}, a GestureDetector (Gesture.Exclusive(Pan(activeOffsetX ±2), Tap)) on a tab screen fails on iOS in two deterministic ways, depending on whether the tab was focused at cold start:
Variant A — tab mounted unfocused at cold start, then switched to: Gesture.Tap never fires (no onBegin), while the Gesture.Pan in the same Exclusive works. The dead Tap persists for the entire session — pressing other RN views, tab switches, and stack pushes do not recover it. Reproduced 3/3 cold sessions; revived 0/3.
Variant B — tab focused at cold start, switched away and back: both Tap and Pan are dead. Pressing a plain RN on the same screen revives both immediately. Reproduced 3/3; revived 3/3.
A plain RN
beside the detector works at all times in both variants, so touch delivery into React is healthy — the failure is in the gesture-handler path. Removing either detachInactiveScreens={false} or lazy: false makes both variants unreproducible. Not observed on Android.
Looks related to #2920 (iOS, GestureDetector "loses connection"; fixed for the pushed-screen case in #2925) — but this reproduces on gesture-handler 2.32 with kept-alive tab roots, and Variant A is not recoverable by touching elsewhere, only by remounting the detector.
Steps to reproduce
Requires: iOS, tab navigator with detachInactiveScreens={false} and screenOptions={{ lazy: false }}.
Variant A (repo ships this config):
- npm install && npx expo start, open in Expo Go on a physical iPhone.
- Cold start — app opens on the "Other" tab. Touch nothing.
- Switch to the "Counter" tab.
- Tap the blue GestureDetector box → taps stays 0 (BUG). Drag it → pans increments.
- Press the plain RN Button → works, but taps stays dead for the whole session (3/3 dead, 0/3 revived).
Variant B (one-line change: initialRouteName="CounterTab"):
- Cold start — app opens on the "Counter" tab.
- Switch to "Other", then back to "Counter".
- Tap and drag the box → both taps and pans stay 0 (BUG).
- Press the plain RN Button → both revive immediately and work thereafter (3/3 dead, 3/3 revived).
Expected: gestures fire from the first touch in both variants.
A link to a Gist, an Expo Snack or a link to a repository based on this template that reproduces the bug.
https://github.com/muhasabahhub/gh-taproot
Gesture Handler version
2.32.0
React Native version
0.86.3
Platforms
iOS
JavaScript runtime
Hermes
Workflow
Using Expo Go
Architecture
New Architecture (Fabric)
Build type
Debug mode
Device
Real device
Device model
IPhone 15 - iOS 26.6.1
Acknowledgements
Yes
Description
With a bottom-tab navigator using detachInactiveScreens={false} and screenOptions={{ lazy: false }}, a GestureDetector (Gesture.Exclusive(Pan(activeOffsetX ±2), Tap)) on a tab screen fails on iOS in two deterministic ways, depending on whether the tab was focused at cold start:
Variant A — tab mounted unfocused at cold start, then switched to: Gesture.Tap never fires (no onBegin), while the Gesture.Pan in the same Exclusive works. The dead Tap persists for the entire session — pressing other RN views, tab switches, and stack pushes do not recover it. Reproduced 3/3 cold sessions; revived 0/3.
Variant B — tab focused at cold start, switched away and back: both Tap and Pan are dead. Pressing a plain RN on the same screen revives both immediately. Reproduced 3/3; revived 3/3.
A plain RN
beside the detector works at all times in both variants, so touch delivery into React is healthy — the failure is in the gesture-handler path. Removing either detachInactiveScreens={false} or lazy: false makes both variants unreproducible. Not observed on Android.Looks related to #2920 (iOS, GestureDetector "loses connection"; fixed for the pushed-screen case in #2925) — but this reproduces on gesture-handler 2.32 with kept-alive tab roots, and Variant A is not recoverable by touching elsewhere, only by remounting the detector.
Steps to reproduce
Requires: iOS, tab navigator with detachInactiveScreens={false} and screenOptions={{ lazy: false }}.
Variant A (repo ships this config):
Variant B (one-line change: initialRouteName="CounterTab"):
Expected: gestures fire from the first touch in both variants.
A link to a Gist, an Expo Snack or a link to a repository based on this template that reproduces the bug.
https://github.com/muhasabahhub/gh-taproot
Gesture Handler version
2.32.0
React Native version
0.86.3
Platforms
iOS
JavaScript runtime
Hermes
Workflow
Using Expo Go
Architecture
New Architecture (Fabric)
Build type
Debug mode
Device
Real device
Device model
IPhone 15 - iOS 26.6.1
Acknowledgements
Yes