software-mansion / software-mansion/react-native-gesture-handler
[iOS ≤ 18] RN Pressable inside RNGH FlatList/ScrollView never fires onPress when a Reanimated :active pseudo-selector is attached (touch is cancelled)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 6.8k
- Forks
- 1.1k
- Avg merge
- 1d 6h
- Merged PRs (30d)
- 50
Description
Description
A react-native Pressable rendered inside a react-native-gesture-handler FlatList (or ScrollView) stops firing onPress on iOS 17 and iOS 18 as soon as the pressable carries a Reanimated CSS :active pseudo-selector style. onPressIn and onPressOut fire, onTouchCancel fires, onPress never does. The same tree works on iOS 26, works with react-native's own FlatList/ScrollView, and works without the :active style.
Reanimated implements :active on iOS by attaching a UILongPressGestureRecognizer with minimumPressDuration = 0 and cancelsTouchesInView = NO to the view (REAPseudoSelectorObserver.mm). RNGH's RNNativeViewHandler forces the wrapped UIScrollView to delaysContentTouches = YES (apple/Handlers/RNNativeViewHandler.mm), whereas RN's scroll view keeps it NO. On iOS ≤ 18 that combination results in RCTSurfaceTouchHandler receiving touchesCancelled:, so RN's Pressability terminates the press and drops onPress. iOS 26 no longer cancels the touch.
Results from the minimal repro below (same result for a still tap and a tap with a few points of finger movement):
| Variant | iOS 26.5 sim | iOS 18.6 sim | iOS 17.5 sim |
|---|---|---|---|
RNGH FlatList / RN Pressable with :active |
onPress fires | no onPress, onTouchCancel fires |
no onPress, onTouchCancel fires |
RNGH FlatList / RN Pressable, :active on a child Animated.View |
fires | no onPress | no onPress |
RNGH FlatList with canCancelContentTouches={false} / RN Pressable :active |
fires | no onPress | no onPress |
RNGH FlatList / RNGH Pressable with :active |
fires | fires (touch still cancelled, ignored) | fires |
RNGH FlatList / RN Pressable without :active |
fires | fires | fires |
RN FlatList or RN ScrollView / RN Pressable with :active |
fires | fires | fires |
No list / RN Pressable with :active |
fires | fires | fires |
I am filing this here because the RNGH scroll wrapper is the ingredient that makes RN's touch cancellable;
Expected behaviour
onPress fires for an RN Pressable inside an RNGH FlatList regardless of the Reanimated :active style, as it does on iOS 26 and inside RN's own FlatList.
Actual behaviour
On iOS 17 and 18 the touch is cancelled once the :active recogniser is attached: onPressIn → onTouchCancel → onPressOut, no onPress.
Steps to reproduce
- Create a fresh RN app (New Architecture) with react-native-gesture-handler and react-native-reanimated, wrap the root in
GestureHandlerRootView. - Replace
App.tsxwith the snippet below. - Run on an iOS 17 or 18 simulator (iPhone 15 / iOS 17.5 and iPhone 16 / iOS 18.6 used here).
- Tap a card in row 1. Observe
in 1 / press 0 / out 1 / cancel 1. - Tap a card in row 2 (RNGH Pressable) or row 3 (no
:active). Observepress 1. - Repeat on an iOS 26 simulator: every row reaches
press 1.
A link to a Gist, an Expo Snack or a link to a repository based on this template that reproduces the bug.
https://gist.github.com/roy-ling/c17556168855ea787011729f6284d907
Gesture Handler version
2.31.2
React Native version
0.83.10
Platforms
iOS
JavaScript runtime
Hermes
Workflow
Using Expo Prebuild or an Expo development build
Architecture
New Architecture (Fabric)
Build type
None
Device
Real device
Device model
iPhone 13 Pro on iOS 18.7
Acknowledgements
Yes
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the linked gist and reproduce the cancellation on iOS 17 or 18. Read REAPseudoSelectorObserver.mm alongside apple/Handlers/RNNativeViewHandler.mm, focusing on the active recognizer and delaysContentTouches behavior. Done means the RN Pressable reaches onPress in the affected RNGH list scenarios while the reported variants remain consistent.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ios, objective-c, react-native
- Domain
- mobile
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100