react-native-reanimated icon indicating copy to clipboard operation
react-native-reanimated copied to clipboard

Animated component issue: touchables and TextInputs inside the Animated.ScrollView are not responsive

Open NodoPopkhadze opened this issue 1 year ago • 6 comments

Description

I'm encountering an issue with the Animated component in React Native. When using Animated.ScrollView alongside Animated.View, the touchable components and TextInput inside the Animated.ScrollView are not responsive after scrolling. This issue occurs only on the fabric architecture and only on a real device.

The provided demo is quite primitive and has the purpose of demonstrating the bug.

This bug was originally found in the react-native-keyboard-controller library, which uses a similar solution for keyboard panning. For a more detailed example of this bug, you can visit the react-native-keyboard-controller repository and check the AwareScrollViewStickyFooter example.

Also note that if you change React Native touchables (e.g., TouchableOpacity, TouchableHighlight) to "react-native-gesture-handler" touchable components, the problem is solved. Additionally, react-native-gesture-handler TextInput becomes responsive in Animated.ScrollView. However, when a TextInput component from react-native-gesture-handler is used, touching it to input text prevents scrolling of the screen. So bug remains problematic. https://github.com/software-mansion/react-native-reanimated/assets/47716245/4b27cc16-c47d-4f12-9381-1f623eb2e11f

Steps to reproduce

  1. Create a new React Native project
  2. Import Animated from 'react-native'
  3. Add an Animated.ScrollView with some touchable content and TextInput components
  4. Add an Animated.View alongside the Animated.ScrollView
  5. Run the application on a real device using the fabric architecture
  6. Scroll the Animated.ScrollView a little bit
  7. Try to click any TextInput or button

Snack or a link to a repository

https://github.com/NodoPopkhadze/ReanimatedBugExample

Reanimated version

3.9.0

React Native version

0.74.1

Platforms

Android

JavaScript runtime

Hermes

Workflow

React Native

Architecture

Fabric (New Architecture)

Build type

Debug app & production bundle

Device

Real device

Device model

Samsung Galaxy S21

Acknowledgements

Yes

NodoPopkhadze avatar Jun 03 '24 10:06 NodoPopkhadze

Having the same issue for 3.10.1 version.

datachanturia avatar Jun 03 '24 12:06 datachanturia

Hey @NodoPopkhadze @datachanturia, the issue seems to be fixed in the newest (3.12) Reanimated version. Please check it out and let me know if it helped!

szydlovsky avatar Jun 06 '24 16:06 szydlovsky

Hi @szydlovsky, unfortunately, the issue persists. The behaviour is still the same across all touchable or TextInput components. The bug shows up after scrolling slightly and then attempting to interact with the pressable components(TouchableOpacity, TextInputs and etc).

It’s important to note that this issue only occurs on real Android devices and only on new/fabric architecture. it works fine on an emulator. Additionally, I have updated the Reanimated library to the latest version in the provided repository, but the problem remains unresolved.

NodoPopkhadze avatar Jun 07 '24 07:06 NodoPopkhadze

+1. Have this issue for 3.12.1. Any Pressable component inside an Animated.ScrollView requires several taps to trigger a response, or it is not responsive at all. Testing on both an emulator and physical device (iOS).

jakecurreri avatar Jun 28 '24 14:06 jakecurreri

@jakecurreri would you be able to provide a reproduction (or a code snippet) for you iOS issue?

szydlovsky avatar Jul 01 '24 10:07 szydlovsky

@szydlovsky sure. Here is an example of one Pressable inside the Animated.ScrollView. I have more Pressable components inside the view, and all have the same issue.

The ScrollView component:

...
const scrollY = useSharedValue(0);
const scrollHandler = useAnimatedScrollHandler(event => {
   scrollY.value = event.contentOffset.y;
});
...
return (
   <>
      <AnimatedBlock scrollY={scrollY} />
      <Animated.ScrollView
        showsVerticalScrollIndicator={false}
        contentContainerStyle={styles.screen}
        onScroll={scrollHandler}
        scrollEventThrottle={16}
      >
          <Pressable
            onPress={() => navigation.goBack()}
            style={styles.back}
            hitSlop={16}>
            <ChevronLeftIcon color="#FFFFFF" size={22} />
          </Pressable>
         {...content}
      </Animated.ScrollView>
   </>
)

And the AnimatedBlock:

...
const animatedStyle = useAnimatedStyle(() => {
   const translateYValue = scrollY.value > scrollThreshold ? 0 : -50;
   translateY.value = withTiming(translateYValue);
   return {
      transform: [{translateY: translateY.value}],
   };
 });
 ...
 return (
     <Animated.View style={animatedStyle}>
     {...content}
     </Animated.View>
 )

I've also tried upgrading to the latest release candidate and downgrading all the way to 3.10. No luck.

jakecurreri avatar Jul 01 '24 13:07 jakecurreri

Any update on this? We decided to disabled fabric on android until this is resolved.

PartypayNL avatar Dec 06 '24 09:12 PartypayNL

Also having the same issue with this

jacquesvdhorst avatar Jan 08 '25 11:01 jacquesvdhorst

This seems to work for me..

<View style={{ flex: 1 }} pointerEvents="box-none"> {/* Your scrollable content here */} </View>

TomUngerer avatar Feb 06 '25 13:02 TomUngerer

This seems to work for me..

<View style={{ flex: 1 }} pointerEvents="box-none"> {/* Your scrollable content here */}

I was getting the issue in ScrollView from react-native and this worked for me. I think the issue was that flex:1 was not getting measured or computed by react-native for some reason correctly.

My code now essentially is,

<View style={{flex: 1}} pointerEvents="box-none" />
<ScrollView/>
...
</ScrollView>
</View>

Kartik4152 avatar Feb 11 '25 18:02 Kartik4152

Hi there! After some digging, we discovered that the issue is from React Native itself. It appears to be caused by outdated state being cloned, which results in an incorrect hitbox being applied to Pressable components - you can read more about it in this issue (big kudos to @bartlomiejbloniarz ).

So, to fix that you can apply following feature flags to your project (/android/gradle.properties):

updateRuntimeShadowNodeReferencesOnCommit=true
useShadowNodeStateOnClone=true

If you want to dig more into this feature flags you can go to the related PR.

I've checked and this fixed this on your example, if you encounter any trouble feel free to inform us and we will reopen the issue.

patrycjakalinska avatar Apr 25 '25 08:04 patrycjakalinska