Skip to content
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

Scroll Bug in NestableScrollContainer #497

Open
CharlesZim opened this issue Aug 14, 2023 · 6 comments
Open

Scroll Bug in NestableScrollContainer #497

CharlesZim opened this issue Aug 14, 2023 · 6 comments

Comments

@CharlesZim
Copy link

This package has external dependencies of react-native-reanimated and react-native-gesture-handler which must be installed separately. Before opening an issue related to animations or gestures please verify that you have completed ALL installation steps, including the changes to MainActivity.

Describe the bug
When using NestableScrollContainer with react-native-draggable-flatlist, I noticed that if I try to scroll in a different direction while a scroll motion is still ongoing, it works fine. However, if I wait for the scroll to complete and then attempt to scroll again, depending on the gesture, it often fails to scroll.

To Reproduce
This issue can be reproduced in the official Snack: "https://snack.expo.dev/@computerjazz/draggable-flatlist-examples". Navigate to the "Nested" Screen. Try scrolling up and, before the scroll completes, scroll down (or vice versa). It works as expected. However, if you wait for the scroll to complete and then attempt to scroll again, you will encounter the issue.

Platform & Dependencies
Please list any applicable dependencies in addition to those below (react-navigation etc).

  • react-native-draggable-flatlist version: 4.0.1
  • Platform: iOS
  • React Native or Expo version: 0.72.3
  • Reanimated version: 3.4.2
  • React Native Gesture Handler version: 2.12.1

Additional context
I have also tried replacing NestableDraggableFlatList with a regular FlatList, and it worked without issues. This leads me to believe that the problem might be specific to NestableDraggableFlatList.

@zekicanAYDIN
Copy link

+1

@Samad198
Copy link

Samad198 commented Dec 4, 2023

I am having the same issue. The frequency of the bug seems do decrease as the value of the activationDistance prop increases

@CarterSimonson
Copy link

This seems to be caused by the ScrollView conflicting with the GestureDetector component that DraggableFlatList is using internally. Removing the gesture detector fixes the scroll issue (but breaks everything else obviously)

This issue in the react-native-gesture-handler repo seems relevant. I haven't found a workaround yet but will update here if I do.

@CarterSimonson
Copy link

I was able to find a workaround -> CarterSimonson#1

Here's what I ended up doing:

  • Update the PanHandler in DraggableFlatList to utilize an enabled state.
  • Compose a simultaneous tapGesture that replaces the "drag" handler returned to list items
    • Set the shared enabled state to true when the tapGesture is pressed down.
    • Reset enabled to false on press up.

I initially tried controlling the enabled state from within the drag function but was getting some gnarly race conditions.

This results in the following behavior:

  • If the user attempts to drag without triggering the tapGesture, the panGesture will fail and allow the regular scroll event.
  • If the user drags on the tappable area (the drag icon for me in this case), the tapGesture will fire simultaneously and set the enabled state to true. The panGesture will activate and track the pan events.

This works but unfortunately required a breaking change to the API.

Demo:

302495005-eaf49342-e18d-4a6a-beb7-2d97ab192ae8.mov

@SethCram
Copy link

Hi @CarterSimonson could you provide some of the code of how you got this working? It doesn't seem your PR fixed this issue by default or I think I'd be seeing my issue resolved unless I need to update react-native-gesture-handler library to the latest. Only solution I've found to this is increasing activationDistance by a gross amount and lowering it when dragging item

@CarterSimonson
Copy link

CarterSimonson commented Aug 21, 2024

Hey @SethCram,

My goal was to only allow the elements to be dragged when a button on each of them was clicked and dragged:
image

Here's a code snippet of the workaround from my component that wraps this drag button on each of my list items. The only change to the way the library is used is that a tapGesture from RN gesture handler is passed as an argument to renderItem. The drag event will not begin unless the tapGesture is fired first, which prevented the scrolling bug in my case.

import { GestureDetector } from 'react-native-gesture-handler';

// Part of the workaround is that a `tapGesture` is now passed as an argument of the renderItem function:
function renderItem({ item, getIndex, tapGesture }: RenderItemParams<KeyedString>) {
  const index = getIndex();

  // The dragging logic will only begin if this tapGesture is fired beforehand
  const right = (
    <GestureDetector gesture={tapGesture}>
      <DragIcon />
    </GestureDetector>
  );

  if (index !== undefined) {
    return (
      <InputListItem
        value={item.value}
        onChangeText={(value) => updateIngredient(value, index)}
        onBlur={() => onBlur(index)}
        right={right}
      />
    );
  }
}
return <NestableDraggableFlatList
  data={ingredients}
  onDragEnd={({ data }) => onChange(data)}
  keyExtractor={(value) => value.id}
  renderItem={renderItem}
/>

One limitation of this is that it doesn't prevent the scrolling bug if the entire list item is a clickable area (like it is in this demo). It takes advantage of the fact that I only needed to support drag events on a small section of each list item.

Hopefully that clears some things up, I am happy to elaborate further if not 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants