react-native-gesture-handler icon indicating copy to clipboard operation
react-native-gesture-handler copied to clipboard

[Pressable] Pressed state is not visible for quick taps inside ScrollView on iOS

Open gigobyte opened this issue 8 months ago • 5 comments

Description

I observe a different order of events inside Pressable if it's inside a RNGH ScrollView, causing the pressed state to not be visible.

https://github.com/user-attachments/assets/d073f9e8-1c07-4858-bd6c-6c6f5a101a8d

Image

Steps to reproduce

Shown on the video inside the description

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/gigobyte/46790a144ceb6ec66609c732a6c103b8

Gesture Handler version

2.27.1

React Native version

0.79.0

Platforms

iOS

JavaScript runtime

None

Workflow

React Native (without Expo)

Architecture

New Architecture (Fabric)

Build type

None

Device

iOS simulator

Device model

No response

Acknowledgements

Yes

gigobyte avatar Jul 11 '25 10:07 gigobyte

Hey! 👋

The issue doesn't seem to contain a minimal reproduction.

Could you provide a snack or a link to a GitHub repository under your username that reproduces the problem?

github-actions[bot] avatar Jul 11 '25 10:07 github-actions[bot]

Hey, this is actually expected behaviour.

On iOS, inside scroll list, there's a system-enforced ~200ms activation delay, which prevents children of the scroll list from activating until they've been pressed down for 200ms without the list moving.

The original RN Pressable ignores this 200ms delay, which is invalid, and doesn't follow the conventional behaviour of other iOS components.

The reason this behaviour does not occur on Android is that Android puts the activation burden on the scroll list element instead of the button element. Instead of waiting 200ms for the button to activate, a movement threshold is put on the list, once the threshold is reached, no child of the list can activate until the scroll list stops moving.

latekvo avatar Jul 11 '25 10:07 latekvo

I assume this is the property you're describing:

// apple/Handlers/RNNativeViewHandler.mm
scrollView.delaysContentTouches = YES;

In that case, is it possible to expose control of that flag? In our case we are upgrading from an old version of RNGH, not the original react-native Pressable, and we didn't observe the delay before.

gigobyte avatar Jul 11 '25 10:07 gigobyte

is it possible to expose control of that flag

Will look into that, but there's a chance that'll break a lot of logic.

we didn't observe the delay before

I just checked, and you're right. While the onPress behaviour didn't change in the new version, the onPressIn no longer fires on the first touch input, and onPressOut no longer fires on cancellation of the first touch input.

This will be fixed.

Tests
onPress* callbacks onPress / functional styling

Branch with the test code visible on the video:

https://github.com/software-mansion/react-native-gesture-handler/tree/%40latekvo/compare-old-new-original-pressables

latekvo avatar Jul 14 '25 10:07 latekvo

Will look into that, but there's a chance that'll break a lot of logic.

We've been running with the flag disabled for 1 month now without any issues on a large userbase. This is fyi for other people also willing to patch it.

gigobyte avatar Aug 11 '25 10:08 gigobyte