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

Doesn't work in a modal #139

Closed
martinezguillaume opened this issue Apr 11, 2018 · 101 comments · Fixed by #1603
Closed

Doesn't work in a modal #139

martinezguillaume opened this issue Apr 11, 2018 · 101 comments · Fixed by #1603
Labels
Bug Can repro It is confirmed we can reproduce the issue Important This seem to be a serious issue and we will need to take a deeper look into it some time soon Platform: Android This issue is specific to Android

Comments

@martinezguillaume
Copy link

Hi !
I have a little issue on Android, onGestureEvent is not trigger when GestureHandler components is on a modal on Android. When I change the modal to a View, it works perfectly 👌

No problem on iOS

@martinezguillaume martinezguillaume changed the title [Android] Doesn't on a modal [Android] Doesn't work on a modal Apr 11, 2018
@martinezguillaume martinezguillaume changed the title [Android] Doesn't work on a modal [Android] Doesn't work in a modal Apr 11, 2018
@kmagiera kmagiera added the bug label Apr 26, 2018
@mordaha
Copy link

mordaha commented Jun 8, 2018

+1
any workaround?

@martinezguillaume
Copy link
Author

I don’t use Modal for now, I just re-create it with a View in absolute position

@mordaha
Copy link

mordaha commented Jun 8, 2018

using modal screen for now, after googling and chats Modal from RN considered too much buggy thing

@csto
Copy link

csto commented Jun 20, 2018

+1

@osdnk
Copy link
Contributor

osdnk commented Jul 10, 2018

Hi, @martinezguillaume, @mordaha, @csto
I did take a look on this issue and I suppose it's not a matter of our library, but RN Core.

@mars-lan
Copy link

@osdnk is this fixable?

@ParhamZare
Copy link

+1 gesture does not work on modal

@ewendel
Copy link

ewendel commented Jan 28, 2019

I also ran into this bug today.

@ghost
Copy link

ghost commented Feb 1, 2019

Same problem. Gesture does not work on modal on Android.
Expo for example

@Dmitrylolo
Copy link

Dmitrylolo commented Feb 26, 2019

Same for me. Tested react-native's PanResponder handlers on modal - works fine.

I have a thoughts about this: when we are linking this library to android project, we are doing next step

@Override
            protected ReactRootView createRootView() {
                return new RNGestureHandlerEnabledRootView(MainActivity.this);
            }

And we know that modal is separate package. May be theres sense to do something same with it?

@samzmann
Copy link

I was using a standard React Native Modal and was experiencing this issue.
I worked around the problem by creating a new screen and displaying it as a modal. I'm using react-native-navigation, so:

Navigation.showModal({
    component: {
      name: navRoutes.ImageModal,
      passProps: { image },
    },
  })

Gestures are working as expected on both iOS and Android, and I still get transparent background that I wanted from my original modal.

@osdnk
Copy link
Contributor

osdnk commented Mar 26, 2019

I have dug into it for a while.

  1. It's a problem of RNGH. Sorry 😒
  2. It happens bc modals are not rendered below an RN root view.
  3. It's fixable by replacing modals' mechanism in a similar way as we do with an RNRootView by wrapping it with some extra logic. See https://github.com/kmagiera/react-native-gesture-handler/blob/master/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootViewManager.java
  4. I have no time to do it now, it's time-consuming work and probably requires copying some code in an RNGH core on Android native side.

If someone wants and has time to do it, I'll happily review it and merge immediately if it would be workable and not too hacky.

@martinezguillaume @mordaha @csto @mars-lan @ParhamZare @ewendel @via-profit @Dmitrylolo @Lavielle

@osdnk
Copy link
Contributor

osdnk commented Mar 26, 2019

Also, I've made a try two months ago.

139da18

Maybe it could be an inspiration for someone 🤷‍♂️

@osdnk osdnk pinned this issue Mar 26, 2019
@AlexUzan
Copy link

AlexUzan commented Apr 4, 2019

Hey @osdnk I need this feature for my app, so I was thinking I could give it a try, but I don't have a lot of experience with RNGestureHandler, or with Android. Could you give me some more insight on what I would need to do to make it work ?
Also I was looking at your previous try, and I would like to know what's missing for it to be finished, and if it could be used as a starting point.

@yqz0203
Copy link

yqz0203 commented Apr 24, 2019

same error.

@paolospag
Copy link
Contributor

@kmagiera @osdnk any update on this?
even Touchable*'s don't work inside the modal and this is frustrating

@blohamen
Copy link

+1. i use reanimated-bottom-sheet with modal

@cristianoccazinsp
Copy link

Any updates? Or perhaps, any other modal component that does not suffer from this issue? RN's modal honestly works like quite bad and is full of bugs (such as getting stuck if combined with an alert)

@mars-lan
Copy link

@cristianoccazinsp I ended up using https://github.com/react-native-community/react-native-modal

@cristianoccazinsp
Copy link

cristianoccazinsp commented May 31, 2019 via email

j-piasecki pushed a commit that referenced this issue Sep 24, 2021
Fixes #139

Removed RNGHModalUtils

This class gave access to ReactModalHostView.DialogRootViewGroup in order to
call #onChildStartedNativeGesture() and use instanceof on it. Checks for
ReactRootView / DialogRootViewGroup can be unified by utilizing RootView (which
both of those classes implement).

Always render GestureHandlerRootView

This prevents gestures from not being delivered to RNGH when another
GestureHandlerRootView is used before modal (e.g. from React Navigation).

Note: This isn't an ideal fix since a new orchestrator will be created, preventing modals from interacting with handlers outside of them. However, this use case is rare. Having gestures working in modals is already an improvement.
@joy-betterhalf
Copy link

@jakub-gonet When are you planning the next release with #1603 changes?

@jakub-gonet
Copy link
Member

We're planning on releasing the next version in a month or so. This is a transition from 1.x to 2.x so it may take a bit longer than usual.

@eduardorfreitas93
Copy link

eduardorfreitas93 commented Jan 19, 2022

I'm trying to call the RectButton inside a modal of createStackNavigator(@react-navigation/stack), on android the RectButton doesn't trigger onPress, IOS works perfectly

react-native-gesture-handler: 2.1.1
@react-navigation/native: ^6.0.6
@react-navigation/stack: ^6.0.11

Any solution?

fluiddot pushed a commit to wordpress-mobile/react-native-gesture-handler that referenced this issue Feb 25, 2022
Fixes software-mansion#139

Removed RNGHModalUtils

This class gave access to ReactModalHostView.DialogRootViewGroup in order to
call #onChildStartedNativeGesture() and use instanceof on it. Checks for
ReactRootView / DialogRootViewGroup can be unified by utilizing RootView (which
both of those classes implement).

Always render GestureHandlerRootView

This prevents gestures from not being delivered to RNGH when another
GestureHandlerRootView is used before modal (e.g. from React Navigation).

Note: This isn't an ideal fix since a new orchestrator will be created, preventing modals from interacting with handlers outside of them. However, this use case is rare. Having gestures working in modals is already an improvement.
@thahermps
Copy link

The use of react-native-portalize fixed this perfectly for me while using React Navigation - here is a fully working Expo Snack for anyone that wants a minimal example of how to get this working in their own project:
https://snack.expo.dev/@thomascoldwell/react-navigation---rngh-root-view-bug-android---portal-fix

Thanks a lot finally this solution worked for me. :)

@prasanthmurugasamy
Copy link

need more assistance.! can you please help me with this?

@zhaiyjgithub
Copy link

zhaiyjgithub commented Jul 7, 2022

For me, I just installed the newest version 2.4.0. And then I use GestureHandlerRootView to wrapper the PanGestureHandler. It works. Remember that don't wrapper the view or others components. Wrapper thePanGestureHandler like below:

 const $panelView = (
    <GestureHandlerRootView>
      <PanGestureHandler onGestureEvent={onGestureEvent}>
        <Animated.View style={[styles.panelView, panelStyle]}>
          {$contentView}
        </Animated.View>
      </PanGestureHandler>
    </GestureHandlerRootView>
  )


@hugoh59
Copy link

hugoh59 commented Aug 3, 2022

For me, I just installed the newest version 2.4.0. And then I use GestureHandlerRootView to wrapper the PanGestureHandler. It works. Remember that don't wrapper the view or others components. Wrapper thePanGestureHandler like below:

 const $panelView = (
    <GestureHandlerRootView>
      <PanGestureHandler onGestureEvent={onGestureEvent}>
        <Animated.View style={[styles.panelView, panelStyle]}>
          {$contentView}
        </Animated.View>
      </PanGestureHandler>
    </GestureHandlerRootView>
  )

This fix does make the component scrollable but it's still super glitchy on android compared to when using the same component outside of a modal.

@first-dev
Copy link

first-dev commented Aug 30, 2022

This happened to me too and belive it or not I solved it by setting backgroundColor of the GesturHandler content (the inner View) to transparent (or any value)
I'm guessing because react-native optimizes views only used for positioning their children and removes them or something and having a backgroundColor forces it to keep the view (please correct me if I'm wrong).

@ser-emejia
Copy link

Still not working on Android 👎

@usedlife
Copy link

Try this: https://docs.swmansion.com/react-native-gesture-handler/docs/installation/#usage-with-modals-on-android

const ExampleWithHoc = gestureHandlerRootHOC(() => (
    <View>
      <DraggableBox />
    </View>
  );
);

export default function Example() {
  return (
    <Modal>
      <ExampleWithHoc />
    </Modal>
  );
}

@Martijncvv
Copy link

RNGH works in a react native Modal if you wrap ONLY the content of the Modal in the GestureHandlerRootView component (see RNGH docs, this comment and this pull request).

But if you wrap the whole app (or a screen that contains the Modal) in GestureHandlerRootView too, RNGH buttons stops working inside the Modal (see why below).

Examples

Example of GestureHandlerRootView used only inside a Modal:

const GHRVInsideModal: React.FC = () => {
  const [visible, setVisible] = useState(false);

  return (
    <>
      <TouchableOpacity onPress={() => setVisible(true)}>
        <Text>Open (it's RN button) - it works</Text>
      </TouchableOpacity>

      <Modal
        animationType="slide"
        transparent
        visible={visible}
      >
        <View style={styles.modal}>
          <RectButton onPress={() => setVisible(false)}>
            <Text>Close (it's RNGH button outside GestureHandlerRootView) - it does not work</Text>
          </RectButton>

          <GestureHandlerRootView>
            <RectButton onPress={() => setVisible(false)}>
              <Text>Close (it's RNGH button inside GestureHandlerRootView) - it works</Text>
            </RectButton>
          </GestureHandlerRootView>
        </View>
      </Modal>
    </>
  );
};

Example of nested GestureHandlerRootView:

const NestedGHRV: React.FC = () => {
  const [visible, setVisible] = useState(false);

  return (
    <GestureHandlerRootView>
      <RectButton onPress={() => setVisible(true)}>
        <Text>Open (it's RNGH button) - it works</Text>
      </RectButton>

      <Modal
        animationType="slide"
        transparent
        visible={visible}
      >
        <View style={styles.modal}>
          <GestureHandlerRootView>
            <RectButton onPress={() => setVisible(false)}>
              <Text>Close (it's RNGH button inside GestureHandlerRootView) - it does not work</Text>
            </RectButton>

            <TouchableOpacity onPress={() => setVisible(false)}>
              <Text>Close (it's RN button) - it works</Text>
            </TouchableOpacity>
          </GestureHandlerRootView>
        </View>
      </Modal>
    </GestureHandlerRootView>
  );
};

Video with two examples:

Screen.Recording.2021-06-29.at.15.06.01.mov
See this repo with two examples.

React navigation

If you create a Modal inside react-navigation's stack and wrap the content of the Modal in GestureHandlerRootView as the documentation says, it reproduces the second example and RNGH buttons in a Modal will not work.

This is happening because react-navigation wraps the stack content in GestureHandlerRootView and your GH root view in a Modal renders as a simple View.

How to fix

Why does the button in the Modal work in the first case, but not in the second?

If we look at the 17th line of the GestureHandlerRootView.android.tsx file we see, that nested gesture handler root views renders as View. If you try to delete 17-22 lines from the GestureHandlerRootView.android.tsx file the second example will start working.

Video reproduced what will be if you delete 17-22 lines from the GestureHandlerRootView.android.tsx file (uploaded to YouTube, because GitHub does not allow uploading large files): RNGH: nested GestureHandlerRootView renders as View

As a result, if the nested GestureHandlerRootView is NOT rendered as a simple View, RNGH buttons in a Modal in Android will work. I created a pull request #1493 that fixes it.

2023, problem is still there, but this worked. Thanks!

@Goowwy
Copy link

Goowwy commented Aug 25, 2023

I got this working using the suggestion for Library authors

<Modal>
    <GestureHandlerRootView style={{width:'100%', height:'100%'}}>
        <myGestureEnabledComponent/>
    </GestureHandlerRootView>
</Modal>

Only tested on my Pixel 5 so far, but things are looking good so far

Works for nexus5x emulator.

not worked when using stack of react-navigation

Thanks its working for me

@ammarfaris
Copy link

Thanks its working for me

Thanks for summarising @Goowwy . Works like a charm in Android modal! You all are life savers!

@steniowagner
Copy link

steniowagner commented Oct 13, 2023

"react": "18.2.0",
"react-native": "0.72.5",
"react-native-gesture-handler": "^2.13.1"

Wrapping the components that uses the RNGH stuff still works like a charm!

Thank you so much everyone!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Can repro It is confirmed we can reproduce the issue Important This seem to be a serious issue and we will need to take a deeper look into it some time soon Platform: Android This issue is specific to Android
Projects
None yet
Development

Successfully merging a pull request may close this issue.