New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[IOS] ScrollView inside FlatList blocks other touchables (children of parent Flatlist) in IOS during scroll #35333
Comments
Detailed RCA - Whenever a component is clicked while the scroll is active the onPress function of the component is not being called, however components that were wrapped with touchable opacity components are highlighted i.e visible visual feedback, basically, the touch is being registered but has not been propagated to the component. The gesture recognizer system in React Native works on the Responder System wherein for a particular view to register and execute certain gestures such as a click or a swipe, the current view needs to have a lock on it i.e it needs to be the current responder for that entire page. The way the Responder System works is that it is a singleton at the global level and at one particular moment of time only one view can be the responder, hence all the other views and any gesture triggered on that view is canceled if that view is not the current responder. One of the issues is when a scroll view is used with onScroll method defined. This is a bubbling event that is emitted from the native to the JS and for a view to consume a particular event and take action on it needs to be the responder since this event is fired every 16 ms on iOS, the scroll view is the current responder until the scrolling is stopped which cancels any other gesture triggered on any other component. As per the entire journey defined in the Responder System, _handleScrollShouldSetResponder method is called again and again to set the scroll view as the current responder which is called in the ResponderEventPlugin from React which then triggers this method and sets the scroll view as the current responder. Another issue is where a FlatList is nested inside a parent FlatList. It exhibits the same behavior as described above. Since a FlatList natively extends ScrollView only, it inherits the same characteristics. After debugging the native implementations and working of ScrollView and it’s events on Android and iOS, and the lifecycle of gestures and the Responder System in React Native and React, I found that _handleScrollShouldSetResponder method is never called on Android but is called on IOS every time an OnScroll event is emitted from native to JS. This method is responsible for setting the scroll view as the current responder. In Android whenever a Scroll Event is emitted, a boolean responderIgnoreScroll set to true is sent as metadata which is consumed in React where the transfer of responder occurs. |
Related issue - #35332 |
tried to use |
Old Reported issue - #10822 |
any help on this? |
In the sample app, I used a FlatList as the vertical parent list and a ScrollView as the child horizontal list. I have also defined onScroll event with scrollEventThrottle flag in ScrollView with a simple toast message to simulate a click action behavior Link to the video - https://drive.google.com/file/d/1I6FQMkCYzBgSNQO-LR8t2oumgxt2mBFR/view?usp=sharing |
any update on this? |
I have exactly the same problem |
I fixed this issue in this PR -> #35925 it is working fine for me after the above fix, you can test it out for yourself :) |
@PratthamArora I think I have the same issue, or at least very similar. Is difficult to reproduce, but basically it happens when I scroll and open a Modal related view right after. Sometimes even navigating to a view (pressing a touchable while scrolling or finishing scrolling) that shows a modal component and coming back, then the buttons in that first view are unresponsive. |
It should work for that usecase as well, you can try and let us know |
@PratthamArora I'm on 0.70.6. Do you think your changes are compatible for a patch-package in that version? |
@PratthamArora BTW, your pull request was close by stale status. Maybe needs a bump to activated. Or let me know how can I help to get it activated again |
I did a patch on my version of RN and unfortunately it didn't work for this case :( |
FYI, I found that my issue got fixed replacing TouchableOpacity with the one from react-native-gesture-handler |
I use |
Description
While scrolling and clicking on any other component does not trigger any action.
A ScrollView inside FlatList blocks other clickable components (children of parent FlatList) in IOS.
This issue happens in Scrollview only when the onScroll event is used and works fine if it is not used.
Version
0.66.0, 0.69.0
Output of
npx react-native info
System:
OS: macOS 12.1
CPU: (8) x64 Apple M1 Pro
Memory: 28.88 MB / 16.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 14.10.0 - ~/.nvm/versions/node/v14.10.0/bin/node
Yarn: 1.22.19 - ~/.nvm/versions/node/v14.10.0/bin/yarn
npm: 6.14.8 - ~/.nvm/versions/node/v14.10.0/bin/npm
Watchman: Not Found
Managers:
CocoaPods: 1.11.0 - /usr/local/bin/pod
SDKs:
iOS SDK:
Platforms: iOS 15.0, DriverKit 20.4, macOS 11.3, tvOS 15.0, watchOS 8.0
Android SDK: Not Found
IDEs:
Android Studio: 2021.2 AI-212.5712.43.2112.8815526
Xcode: 13.0/13A233 - /usr/bin/xcodebuild
Languages:
Java: 14.0.2 - /usr/bin/javac
npmPackages:
@react-native-community/cli: Not Found
react: 18.0.0 => 18.0.0
react-native: 0.69.6 => 0.69.6
react-native-macos: Not Found
npmGlobalPackages:
react-native: Not Found
Steps to reproduce
inside a parent vertical flatlist, use a horizontal child Scrollview.
While scrolling the child scrollview the other children of the parent flatlist cannot trigger onPress. They are blocked.
Snack, code example, screenshot, or link to a repository
import React, { Component } from 'react';
import { View, Text, TouchableOpacity, SafeAreaView, FlatList, ScrollView } from 'react-native';
const App = ()=> {
const renderListItem = ({ item, index }: any) => {
return (
<ScrollView
onScroll={() => {
console.log(" onScroll called scrollview");
}
}
scrollEventThrottle={16}
horizontal
}
export default App
The text was updated successfully, but these errors were encountered: