software-mansion / react-native-gesture-handler

Declarative API exposing platform native touch and gesture system to React Native.
https://docs.swmansion.com/react-native-gesture-handler/
MIT License
5.83k stars 952 forks source link

GestureDetector must be used as a descendant of GestureHandlerRootView. Otherwise the gestures will not be recognized #2837

Closed spthomas5 closed 3 weeks ago

spthomas5 commented 1 month ago

Description

I previously was not getting this error, but I recently updated many of my libraries (this includes Expo SDK 50) and now when I go on my dev build, I get this error wherever I use GestureDetector. This includes the camera, where it handles double tapping to flip the camera. It also includes all screens where posts are displayed, where it handles double tapping to like. However, my TestFlight app works fine, including the double tap gestures that I use. I'm not sure why I get this error in the first place, as I already have GestureHandlerRootView around my entry point.

Steps to reproduce

This is my index.js

import "react-native-gesture-handler";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { StyleSheet } from "react-native";
import Welcome from "./components/Welcome";
import { BottomSheetModalProvider } from "@gorhom/bottom-sheet";

export default function Page() {
  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <BottomSheetModalProvider>
        <Welcome></Welcome>
      </BottomSheetModalProvider>
    </GestureHandlerRootView>
  );
}

And this is an example of my use of GestureDetector

<GestureDetector gesture={Gesture.Exclusive(doubleTap)}>
          <View style={{ flex: 1, justifyContent: "flex-end" }}>
             # code not included, but this is just my camera and the camera buttons
          </View>
</GestureDetector>

Snack or a link to a repository

None

Gesture Handler version

2.14.0

React Native version

0.73.6

Platforms

iOS

JavaScript runtime

Hermes

Workflow

Expo managed workflow

Architecture

None

Build type

None

Device

Real device

Device model

iPhone 14 Pro, iOS 17.1.2

Acknowledgements

Yes

github-actions[bot] commented 1 month ago

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?

spthomas5 commented 1 month ago

As of now I seem to have gotten around this issue by wrapping all instances of GestureDetector with GestureHandlerRootView, but I'm not sure if this is the intended solution.

<GestureHandlerRootView style={{ flex: 1 }}>
          <GestureDetector gesture={Gesture.Exclusive(doubleTap)}>
            <Image
              source={item.source}
              style={{
                height: windowHeight / 1.8,
                width: windowWidth,
                marginTop: "5%",
                alignSelf: "center",
              }}
              transition={1000}
              contentFit="cover"
              cachePolicy={"disk"}
            />
          </GestureDetector>
</GestureHandlerRootView>
m-bert commented 1 month ago

Hi @spthomas5! I can't see it directly in your snippets, but our guess is that you are using GestureDetector inside modal. Since they represent another view hierarchy, you should also wrap modal's children into GestureHandlerRootView

Also, you don't have to pass {flex: 1} into GestureHandlerRootView since this is already done by us (added in #2757).

Edit:

PR with default {flex: 1} was released yesterday, so it is possible that it might not be available in your application yet.

spthomas5 commented 1 month ago

@m-bert Thank you for the reply. Thanks to your help, I no longer receive the error. However, now my modal (BottomSheetModal from gorhom) no longer works as it did before. I understand if you are not familiar with the library, but if you want to take a look, I have more details here. https://github.com/gorhom/react-native-bottom-sheet/issues/1779 If not, no worries. I appreciate your help!

m-bert commented 3 weeks ago

I'm glad that you don't receive errors anymore. I'm not that familiar with react-native-bottom-sheet so probably I won't be able to help. As I see you've already created an issue in their repository, therefore I'll close this one. If you find out that the problem still lies in Gesture Handler, feel free to open new issue.

luogao commented 19 hours ago

Why use GestureHandlerRootView? It's not user-friendly. For instance, when I create a custom component and I want to inform the user that this component needs to be wrapped in a GestureHandlerRootView at the top level of the element tree. If I place the root component inside the custom component, it could potentially mess up the user's layout hierarchy and styles.

m-bert commented 4 minutes ago

Why use GestureHandlerRootView? It's not user-friendly.

In order to work properly, our gesture system requires root view on Android. It was there from the beginning and, while we understand that this API may not be the best, it is necessary. We try to make it more user-friendly with PRs like adding {flex: 1;} by default. If you have any other suggestions we will be glad to receive them.

when I create a custom component and I want to inform the user that this component needs to be wrapped in a GestureHandlerRootView

I don't understand why you should tell your users that they need to use our root view. Are you maintaining some sort of library?

If I place the root component inside the custom component, it could potentially mess up the user's layout hierarchy and styles.

Same here. Why it would mess up user's hierarchy? Root view is just View that allows gesture handler to work - you can style it as you would style normal view.