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.85k stars 954 forks source link

Doesn't work in a modal #139

Closed martinezguillaume closed 2 years ago

martinezguillaume commented 6 years ago

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

mordaha commented 5 years ago

+1 any workaround?

martinezguillaume commented 5 years ago

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

mordaha commented 5 years ago

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

csto commented 5 years ago

+1

osdnk commented 5 years ago

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 commented 5 years ago

@osdnk is this fixable?

ParhamZare commented 5 years ago

+1 gesture does not work on modal

ewendel commented 5 years ago

I also ran into this bug today.

ghost commented 5 years ago

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

Dmitrylolo commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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

https://github.com/kmagiera/react-native-gesture-handler/commit/139da18039683bed3c439c991c7eaf802086bf86

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

AlexUzan commented 5 years ago

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 commented 5 years ago

same error.

paolospag commented 5 years ago

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

blohamen commented 4 years ago

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

cristianoccazinsp commented 4 years ago

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 commented 4 years ago

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

cristianoccazinsp commented 4 years ago

Odd. That component is supposed to use react's modal internally. Did it make a difference to you?

El jue., 30 de mayo de 2019 14:38, Mars Lan notifications@github.com escribió:

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

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/kmagiera/react-native-gesture-handler/issues/139?email_source=notifications&email_token=ALU263ACF3LNSRSPFWR45ELPYAGJTA5CNFSM4EZ6UZL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODWS7SOQ#issuecomment-497416506, or mute the thread https://github.com/notifications/unsubscribe-auth/ALU263GRH2KHBXUZBGHNKA3PYAGJTANCNFSM4EZ6UZLQ .

mars-lan commented 4 years ago

@cristianoccazinsp It only uses RN's modal to cover the screen, which can be disabled by setting coverScreen to false

jvaclavik commented 4 years ago

@cristianoccazinsp It only uses RN's modal to cover the screen, which can be disabled by setting coverScreen to false

But is there a way how to show fullscreen modal with this prop which is not rendered in root component of the app?

mars-lan commented 4 years ago

@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.

owinter86 commented 4 years ago

This may not resolve all use cases but you can enable gestures in react native modal when setting the prop propagateSwipe to true.

qalqi commented 4 years ago

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', } }) }

djorkaeffalexandre commented 4 years ago

@osdnk fixed it?

romanonthego commented 4 years ago

This one is was so much pain. I've spend some time before resolving to google it, pull my hairs out trying to figure out why on earth same component works on iOS and on android but only in some places inside application

deflorilemarului commented 4 years ago

we have the same issue - it doesn't work on modal. i wonder if anyone is working on this or know of any status update ? do we need to drop this library and switch to RN pan handlers ? any suggestion ?

kesha-antonov commented 4 years ago

https://github.com/react-native-community/react-native-modal doesn't work too

lucasmoreiradev commented 4 years ago

Same here. RectButton doesn't work inside https://github.com/react-native-community/react-native-modal

romanonthego commented 4 years ago

@deflorilemarului @kesha-antonov @fauker Will spare you some time, neither Modal, nor Modal-based packages (if they don't require you to link native dependencies - they are based on react-native's Modal) will help you (I've tried all of them, basically). All of gesture- 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:

  1. Use any other library if you are using modals. You may require rewrite some swipe-based components to PanResponder; this on is pain, but pretty straightforward;
  2. Use modals that are 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 any useContext() calls due to children being rendered above context providers; does not work for us, since navigation context is lost;
  3. Use modals provided by navigation library (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.

radinreth commented 4 years ago

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 file

Screen Shot 2019-11-30 at 12 17 07 PM

Hope it helps

jeffdico commented 4 years ago

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 file

Screen Shot 2019-11-30 at 12 17 07 PM

Hope it helps

Yes, this worked perfectly for me. I almost got frustrated looking for solutions on making my android app swippable.

RZsam commented 4 years ago

still not working if change modal to view everything work just fine...

Psiiirus commented 4 years ago

Hi @romanonthego ,

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.

Can you please tell me what to patch in side my native android code?

osdnk commented 4 years ago

whop https://github.com/software-mansion/react-native-gesture-handler/pull/937

grahammendick commented 4 years ago

@osdnk That's exciting. Will it work with a DialogFragment as well?

samcampisi commented 4 years ago

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)

  renderSearchScreen = () => {
    const { showSearchHistory } = this.state;
    const ExampleWithHoc = gestureHandlerRootHOC(() => {
      return (
        <View style={genericStyles.container}>
          <SearchScreen
            searchBar={{
              ...this.searchBar,
              searchQuery: this.props.searchQuery,
            }}
            onBackPress={() => {
              this.setState({ showSearchHistory: false });
            }}
          />
        </View>
      );
    });

    if (showSearchHistory) {
      return (
        <RNModal
          animationType="fade"
          transparent
          visible={this.state.showSearchHistory}
          onRequestClose={() => {}}>
          <ExampleWithHoc />
        </RNModal>
      );
    }

    return null;
  };

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).

mxmzb commented 4 years ago

whop #937

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

mxmzb commented 4 years ago

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 basically Stack.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:

react-native@0.61.5
@react-navigation/native@5.0.9
@react-navigation/stack@5.1.1

I'll try to setup a demo repo ASAP, let me know if I can provide any more helpful info.

mxmzb commented 4 years ago

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 the PanGestureHandler becomes functional and unfunctional.

https://github.com/mxmzb/react-native-breakable-app

dicabrio commented 4 years ago

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

import { SafeAreaView, Button } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack'

import { enableScreens } from 'react-native-screens';
enableScreens(); // <-- this fucked it up

const Screen1 = ({ navigation }) => {
    return (
      <SafeAreaView style={{ flex: 1 }}>
        <Button title="Open Modal" onPress={() => navigation.push('Modal')} />
      </SafeAreaView>
    )
  }

  const Screen2 = ({ navigation }) => {
    return (
      <SafeAreaView style={{ flex: 1 }}>
        <Button title="Close Modal" onPress={() => navigation.goBack()} />
      </SafeAreaView>
    )
  }

const App = () => {

return (
        <NavigationContainer>
          <Stack.Navigator headerMode="none">
            <Stack.Screen name="Main" component={Screen1} />
            <Stack.Screen name="Modal" component={Screen2} />
          </Stack.Navigator>
        </NavigationContainer>
  )

}

Then I removed this line; enableScreens();

And then it worked correctly on Android.

gideaoms commented 4 years ago

A little trick to solve it inside a modal:

import { TouchableWithoutFeedback } from 'react-native';
import { RectButton } from 'react-native-gesture-handler';
<TouchableWithoutFeedback onPress={...}
    <RectButton>
         ...
    </RectButton>
</TouchableWithoutFeedback>
amidulanjana commented 4 years ago

I am having similar issue. Any work around ?

julianoddreis commented 4 years ago

I was trying to use https://github.com/osdnk/react-native-reanimated-bottom-sheet inside a modal, and it's not possible, I finally solved with react-navigation screen animation:

https://github.com/osdnk/react-native-reanimated-bottom-sheet/issues/143#issuecomment-614300015

KawaljeetSBagga commented 3 years ago

A little trick to solve it inside a modal:

import { TouchableWithoutFeedback } from 'react-native';
import { RectButton } from 'react-native-gesture-handler';
<TouchableWithoutFeedback onPress={...}
    <RectButton>
         ...
    </RectButton>
</TouchableWithoutFeedback>

Hey @gideaoms . I wonder how did your comment went unnoticed here. It definitely does the trick. Thanks man!

chj-damon commented 3 years ago

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 the PanGestureHandler becomes functional and unfunctional.

https://github.com/mxmzb/react-native-breakable-app

then, what is the solution?

AlexAlexandre commented 3 years ago

I'm still having the same problem.... Any solution ou nothing yet ?

cuddeford commented 3 years ago

This is still a problem on 1.6.0

VikasSahu commented 3 years ago

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.