react-native-gesture-handler: Doesn't work in a modal
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
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 93
- Comments: 101 (10 by maintainers)
Commits related to this issue
- Fix modals (#1603) Fixes #139 Removed RNGHModalUtils This class gave access to ReactModalHostView.DialogRootViewGroup in order to call #onChildStartedNativeGesture() and use instanceof on it. ... — committed to software-mansion/react-native-gesture-handler by jakub-gonet 3 years ago
- Fix modals (#1603) Fixes #139 Removed RNGHModalUtils This class gave access to ReactModalHostView.DialogRootViewGroup in order to call #onChildStartedNativeGesture() and use instanceof on it. ... — committed to wordpress-mobile/react-native-gesture-handler by jakub-gonet 3 years ago
- fix (RNGH): BottomSheet buttons are not working Fixed as per https://github.com/software-mansion/react-native-gesture-handler/issues/139 — committed to NigelBreslaw/guardian-ghost by NigelBreslaw 3 months ago
- fix (RNGH): BottomSheet buttons are not working (#1056) Fixed as per https://github.com/software-mansion/react-native-gesture-handler/issues/139 — committed to NigelBreslaw/guardian-ghost by NigelBreslaw 3 months ago
I got this working using the suggestion for Library authors
Only tested on my Pixel 5 so far, but things are looking good so far š
A little trick to solve it inside a modal:
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:Example of nested
GestureHandlerRootView
:Video with two examples:
https://user-images.githubusercontent.com/35278731/123794634-b9bcbb80-d8eb-11eb-9780-bb7713652b33.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 simpleView
.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 theGestureHandlerRootView.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):As a result, if the nested
GestureHandlerRootView
is NOT rendered as a simpleView
, RNGH buttons in a Modal in Android will work. I created a pull request https://github.com/software-mansion/react-native-gesture-handler/pull/1493 that fixes it.Few libraries requires us to deal with native context, if so:
For android, we will need a special care as stated in RNGH document:
Update your
MainActivity.java
fileHope it helps
@cristianoccazinsp I ended up using https://github.com/react-native-community/react-native-modal
@osdnk is this fixable?
whop https://github.com/software-mansion/react-native-gesture-handler/pull/937
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+1 gesture does not work on modal
Still not working on Android š
@gideaoms that tricks may works for button but my use case is to use
PinchGestureHandler
inside the modal.@deflorilemarului @kesha-antonov @fauker Will spare you some time, neither
Modal
, norModal
-based packages (if they donāt require you to link native dependencies - they are based onreact-native
āsModal
) will help you (Iāve tried all of them, basically). All ofgesture-
related components (bottomsheet-behaviour for us) will not register any touches/swipes etc when rendered inside<Modal>...</Modal>
on android; There is 3 solutions I can think of:PanResponder
; this on is pain, but pretty straightforward;portals
. They are not actually portals nor modals- portals are not supported by react-native because there is single application host - but they are working by placing Host Component somewhere up your application and renders Modal content in absolute view above app stack; this one is working solution, but you will loose anyuseContext()
calls due to children being rendered above context providers; does not work for us, sincenavigation
context is lost;react-navigation
); this one works, but API isā¦ not good - for one you could not make a single screen a modal, only a stack can be in modal mode; this one is solution I stick with.Well, there is final solution - patch native android implementation (not possible if you are using expo) or wait for patch in a library and then wait until it merged into expo.
p.s. Donāt get me wrong, this library is amazing, and I cannot stress enough how much I appreciate work being poured into this and how much better the experience for end user, but bugs like this one make me want to pull my hairs out.
+1. i use reanimated-bottom-sheet with modal
+1 any workaround?
To sum up:
react-native
ās<Modal>
component (even though the Component is wrapped in agestureHandlerRootHOC
)wix/react-native-navigation
ās which is shown usingNavigation.showModal
(even though the Screen is wrapped in agestureHandlerRootHOC
)react-navigation
ās push function withmodal: true
, but only when not using the native stack (enableScreens()
/createNativeStackNavigator()
).I can provide more details if required.
This is still a problem on 1.6.0
@kmagiera @osdnk any update on this? even
Touchable*
's donāt work inside the modal and this is frustratingI also ran into this bug today.
import {Platform, Modal} from āreact-nativeā; import {gestureHandlerRootHOC} from āreact-native-gesture-handlerā; import {AnimatedBottomSheet} from āā¦/AnimatedBottomSheetā;
const AnimatedBottomSheetWrapper = Platform.OS === āandroidā ? gestureHandlerRootHOC(AnimatedBottomSheet) : AnimatedBottomSheet;
https://github.com/react-native-community/react-native-modal doesnāt work too
I have dug into it for a while.
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
not worked when using stack of react-navigation
This issue is more than 2 years old, are there any plans to fix this?
Iāve created custom Slider components for my app and canāt use them at all on Android, since a lot of views in my app are Modals
Iāve wrapped every screen and Modal component in a
gestureHandlerRootHoC
(using wix/react-native-navigation)Hey @gideaoms . I wonder how did your comment went unnoticed here. It definitely does the trick. Thanks man!
Try this: https://docs.swmansion.com/react-native-gesture-handler/docs/installation/#usage-with-modals-on-android
@DavidAPears have you tried wrapping you modals in
gestureHandlerRootHOC
?something like this ?
Iāve played around a bit and was able to find the issue. However, I am not sure whatās causing it and how to fix it.
The problem in my case is, that I
react-native-gesture-handler
will not work inside a@react-navigation/stack
, if placed inside a modal (so basicallyStack.Navigator
>SomeScreenComponent
>Modal
>gestureHandlerRootHOC(PanGestureHandler)
fails).If I cut the Stack Navigator out or use the Tab Navigator instead, it works like a charm, so I am pretty sure itās the Stack Navigatorsā fault.
Relevant package versions:
Iāll try to setup a demo repo ASAP, let me know if I can provide any more helpful info.
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.
@jvaclavik I used it in conjunction with https://github.com/callstack/react-native-paper, which has a component called Portal designed specifically for this purpose.
same error.
Thanks its working for me
if you had examples it would be great.
setting coverSreen={false} on modal works. But need my modal cover the screen
Here is a demo app to (almost blank from
npx react-native init
), that will show the issue. You can toggle the stack navigator inside the app and see how thePanGestureHandler
becomes functional and unfunctional.https://github.com/mxmzb/react-native-breakable-app
Thatās amazing! It still doesnāt work with
react-native-modal
for me, though!// edit: Actually, default modal doesnāt work either, but it should, starting from 1.6.0 if I am not mistaken? Will try to find out whatās going wrong
still not working if change modal to view everything work just fineā¦
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:
@jakub-gonet When are you planning the next release with #1603 changes?
After a whole day of debugging
<Portal>
When I did this it did not work:
However this worked:
if i skip any one of these steps it does not work
Works for nexus5x emulator.
I have a similar issue. It seems that the Stack.Navigator doesnāt work well on Android. It doesnāt matter if I use a mode=āmodalā or ācardā.
So i was playing around and had the following code
Then I removed this line;
enableScreens();
And then it worked correctly on Android.
After trying #937 I found out it didnāt work for meā¦
Maybe itās because Iām using wixās react-native-navigation? As far as I know each and every screen is registered with the gestureHandlerRootHOC (the library works perfectly with normal, non modal views).
This is a fragment of the screen in which I tried the RectButton in a Modal (basically as it is in the doc update)
The modal loads when itās supposed to, but the RectButton does not fire the onPress event. I tried making a minimum reproducible demo with a brand new app but then I ran into #848 #676 #835 (possible duplicates of one another).
This issue seems to be related to https://github.com/kmagiera/react-native-screens/issues/61
Donāt use react native screens in android. Tested and working fine with āreanimated-bottom-sheetā
if (Platform.OS === āiosā) { useScreens(); }
This React Navigation Modal config for transparent bg is
ScreenOne: { screen: ScreenOne, navigationOptions: { gesturesEnabled: false }, } { mode: āmodalā, transparentCard: true, headerMode: ānoneā, cardStyle: { backgroundColor: ātransparentā, opacity: 1 }, transitionConfig: () => ({ containerStyle: { backgroundColor: ātransparentā, } }) }
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:Gestures are working as expected on both iOS and Android, and I still get transparent background that I wanted from my original modal.
not worked when using stack of react-navigation
It works for me, thanks. If you want to cover the screen , you can make a customed modal componnet and put it at the top level of component tree, then set style to cover screen, you can set children component (modal content) by Ref.
Combination of
Portal
fromreact-native-portalize
andgestureHandlerRootHOC
works for me. Something like that:Its working for me:
<TouchableWithoutFeedback onPress={() => { console.log("press"); }} > <Text> <RectButton> ... </RectButton> </Text> </TouchableWithoutFeedback>
@waheedakhtar694 , itās using absolute. At least in my case, no problem š
@flyskywhy if react-native-modal-animated doesnāt use a separate activity like react-native-modal then how itās render on top of everything? If itās using an absolute position then it could make a problem in some cases.
Tried every suggestions mentioned above but still no luck yet. Please help its really frustrating. My react native version in 0.62.2 tried with both /react-native-gesture-handler 1.5.6 & 1.6.0.
@cristianoccazinsp It only uses RNās modal to cover the screen, which can be disabled by setting
coverScreen
tofalse
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
And we know that modal is separate package. May be theres sense to do something same with it?