React-native-gesture-handler: Ne fonctionne pas dans un modal

Créé le 11 avr. 2018  ·  71Commentaires  ·  Source: software-mansion/react-native-gesture-handler

Salut !
J'ai un petit problème sur Android, onGestureEvent ne se déclenche pas lorsque les composants GestureHandler sont sur un modal sur Android. Quand je change le modal en vue, cela fonctionne parfaitement 👌

Aucun problème sur iOS

Android Bug Can repro Important

Commentaire le plus utile

Un petit truc pour le résoudre dans un modal:

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

Tous les 71 commentaires

+1
une solution de contournement?

Je n'utilise pas Modal pour le moment, je le recrée simplement avec une vue en position absolue

en utilisant l'écran modal pour le moment, après googler et chats Modal de RN considéré comme trop bogué

+1

Salut, @martinezguillaume , @mordaha , @csto
J'ai jeté un coup d'œil sur cette question et je suppose que ce n'est pas une question de notre bibliothèque, mais RN Core.

@osdnk est-ce réparable?

Le geste +1 ne fonctionne pas en mode modal

J'ai aussi rencontré ce bug aujourd'hui.

Même problème. Le geste ne fonctionne pas en mode modal sur Android .
Expo par exemple

Pareil pour moi. Testé les gestionnaires PanResponder de react-native sur modal - fonctionne très bien.

J'ai une réflexion à ce sujet: lorsque nous lions cette bibliothèque au projet Android, nous passons à l'étape suivante

<strong i="7">@Override</strong>
            protected ReactRootView createRootView() {
                return new RNGestureHandlerEnabledRootView(MainActivity.this);
            }

Et nous savons que modal est un package séparé. Peut-être y a-t-il un sens à faire quelque chose de même avec?

J'utilisais un React Native Modal standard et rencontrais ce problème.
J'ai contourné le problème en créant un nouvel écran et en l'affichant sous forme de modal. J'utilise la navigation react-native , donc:

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

Les gestes fonctionnent comme prévu sur iOS et Android, et j'obtiens toujours un arrière-plan transparent que je voulais de mon modal d'origine.

J'y ai creusé pendant un moment.

  1. C'est un problème de RNGH. Désolé 😒
  2. Il arrive que les modaux bc ne soient pas rendus sous une vue racine RN.
  3. Il est réparable en remplaçant le mécanisme des modaux de la même manière que nous le faisons avec un RNRootView en l'enveloppant avec une logique supplémentaire. Voir https://github.com/kmagiera/react-native-gesture-handler/blob/master/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootViewManager.java
  4. Je n'ai pas le temps de le faire maintenant, c'est un travail fastidieux et nécessite probablement de copier du code dans un noyau RNGH du côté natif d'Android.

Si quelqu'un veut et a le temps de le faire, je serai heureux de l'examiner et de fusionner immédiatement si cela serait réalisable et pas trop piraté.

@martinezguillaume @mordaha @csto @ mars-lan @ParhamZare @ewendel @ Via-profit @Dmitrylolo @LaVielle

De plus, j'ai fait un essai il y a deux mois.

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

Peut-être que ça pourrait être une inspiration pour quelqu'un 🤷‍♂️

Hey @osdnk J'ai besoin de cette fonctionnalité pour mon application, alors je pensais pouvoir l'essayer, mais je n'ai pas beaucoup d'expérience avec RNGestureHandler ou avec Android. Pourriez-vous me donner un aperçu de ce que j'aurais besoin de faire pour que cela fonctionne?
Je regardais aussi votre essai précédent, et j'aimerais savoir ce qui manque pour qu'il soit terminé, et s'il pourrait être utilisé comme point de départ.

même erreur.

@kmagiera @osdnk une mise à jour à ce sujet?
même les Touchable* ne fonctionnent pas dans le modal et c'est frustrant

+1. j'utilise une feuille de fond réanimée avec du modal

Les mises à jour? Ou peut-être, tout autre composant modal qui ne souffre pas de ce problème? Le modal de RN fonctionne honnêtement comme assez mauvais et est plein de bugs (comme rester coincé s'il est combiné avec une alerte)

@cristianoccazinsp J'ai fini par utiliser https://github.com/react-native-community/react-native-modal

Impair. Ce composant est censé utiliser le modal de react en interne. L'a fait
fait une différence pour vous?

El jue., 30 mai 2019 14:38, Mars Lan [email protected]
escribió:

@cristianoccazinsp https://github.com/cristianoccazinsp J'ai fini par
en utilisant https://github.com/react-native-community/react-native-modal

-
Vous recevez cela parce que vous avez été mentionné.
Répondez directement à cet e-mail, affichez-le sur GitHub
https://github.com/kmagiera/react-native-gesture-handler/issues/139?email_source=notifications&email_token=ALU263ACF3LNSRSPFWR45ELPYAGJTA5CNFSM4EZ6UZL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODWS7SOQ#issuecomment-497416506 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/ALU263GRH2KHBXUZBGHNKA3PYAGJTANCNFSM4EZ6UZLQ
.

@cristianoccazinsp Il utilise uniquement le modal de RN pour couvrir l'écran, ce qui peut être désactivé en définissant coverScreen sur false

@cristianoccazinsp Il utilise uniquement le modal de RN pour couvrir l'écran, ce qui peut être désactivé en définissant coverScreen sur false

Mais existe-t-il un moyen d'afficher un mode modal en plein écran avec cet accessoire qui n'est pas rendu dans le composant racine de l'application?

@jvaclavik Je l'ai utilisé en conjonction avec https://github.com/callstack/react-native-paper , qui a un composant appelé Portal conçu spécifiquement à cet effet.

Cela peut ne pas résoudre tous les cas d'utilisation, mais vous pouvez activer les gestes dans react native modal lorsque vous définissez le prop propagateSwipe sur true.

Ce problème semble être lié à https://github.com/kmagiera/react-native-screens/issues/61

N'utilisez pas d'écrans natifs de réaction dans Android. Testé et fonctionne très bien avec 'reanimated-bottom-sheet'

if (Platform.OS === 'ios') {
useScreens ();
}

Cette configuration modale de navigation React pour bg transparent est

ScreenOne: {
écran: ScreenOne,
navigationOptions: {
gesturesEnabled: false
},
}
{
mode: 'modal',
transparentCard: vrai,
headerMode: 'aucun',
cardStyle: {
backgroundColor: 'transparent',
opacité: 1
},
transitionConfig: () => ({
containerStyle: {
backgroundColor: 'transparent',
}
})
}

@osdnk l'a corrigé?

Celui-ci était tellement douloureux.
J'ai passé du temps avant de me résoudre à le google, je me suis tiré les cheveux pour essayer de comprendre pourquoi diable le même composant fonctionne sur iOS et sur Android, mais seulement à certains endroits dans l'application

nous avons le même problème - cela ne fonctionne pas sur modal.
Je me demande si quelqu'un travaille là-dessus ou connaît une mise à jour de statut?
devons-nous supprimer cette bibliothèque et passer aux gestionnaires de pan RN?
toute suggestion ?

Pareil ici. RectButton ne fonctionne pas à l'intérieur de https://github.com/react-native-community/react-native-modal

@deflorilemarului @
Vous épargnera du temps, ni les packages basés sur Modal , ni sur Modal (s'ils ne vous obligent pas à lier les dépendances natives - ils sont basés sur react-native Modal ) vous aidera (je les ai tous essayés, en gros).
Tous les composants associés à gesture- (comportement de bas de page pour nous) n'enregistreront aucun contact / balayage, etc. lorsqu'ils sont rendus à l'intérieur de <Modal>...</Modal> sur Android;
Il y a 3 solutions auxquelles je peux penser:

  1. Utilisez n'importe quelle autre bibliothèque si vous utilisez des modaux. Vous devrez peut-être réécrire certains composants basés sur le balayage en PanResponder ; c'est de la douleur, mais assez simple;
  2. Utilisez des modaux portals . Ce ne sont pas en fait des portails ni des modaux - les portails ne sont pas pris en charge par react-native car il n'y a qu'un seul hôte d'application - mais ils fonctionnent en plaçant le composant hôte quelque part dans votre application et en affichant le contenu modal en vue absolue au-dessus de la pile d'applications; celle-ci est une solution de travail, mais vous perdrez tous les appels useContext() raison des enfants rendus au-dessus des fournisseurs de contexte; ne fonctionne pas pour nous, car le contexte navigation est perdu;
  3. Utilisez les modaux fournis par la bibliothèque de navigation ( react-navigation ); celui-ci fonctionne, mais l'API n'est ... pas bon - pour celui qui ne peut pas faire d'un seul écran un modal, seule une pile peut être en mode modal; celui-ci est la solution avec laquelle je m'en tiens.

Eh bien, il existe une solution finale - patch de l'implémentation native d'Android (pas possible si vous utilisez expo) ou attendez le patch dans une bibliothèque, puis attendez qu'il soit fusionné dans expo.

ps
Ne vous méprenez pas, cette bibliothèque est incroyable, et je ne saurais trop insister sur le fait que j'apprécie le travail qui y est consacré et à quel point l'expérience est meilleure pour l'utilisateur final, mais des bugs comme celui-ci me donnent envie de me tirer les cheveux.

Peu de bibliothèques nous obligent à gérer le contexte natif, si c'est le cas:

Pour Android, nous aurons besoin d'un soin particulier comme indiqué dans le document RNGH :

Mettez à jour votre fichier MainActivity.java
Screen Shot 2019-11-30 at 12 17 07 PM

J'espère que ça aide

Peu de bibliothèques nous obligent à gérer le contexte natif, si c'est le cas:

Pour Android, nous aurons besoin d'un soin particulier comme indiqué dans le document RNGH :

Mettez à jour votre fichier MainActivity.java
Screen Shot 2019-11-30 at 12 17 07 PM

J'espère que ça aide

Oui, cela a parfaitement fonctionné pour moi. Je suis presque frustré de chercher des solutions pour rendre mon application Android swippable.

ne fonctionne toujours pas
si changer de modal pour tout voir fonctionne très bien ...

Salut @romanonthego ,

Eh bien, il existe une solution finale - patch de l'implémentation native d'Android (pas possible si vous utilisez expo) ou attendez le patch dans une bibliothèque, puis attendez qu'il soit fusionné dans expo.

Pouvez-vous s'il vous plaît me dire quoi patcher à côté de mon code Android natif?

@osdnk C'est excitant. Cela fonctionnera-t-il également avec un DialogFragment ?

Après avoir essayé le # 937, j'ai découvert que cela ne fonctionnait pas pour moi ...

C'est peut-être parce que j'utilise la navigation react-native-navigation de wix? Autant que je sache, chaque écran est enregistré avec le gestureHandlerRootHOC (la bibliothèque fonctionne parfaitement avec des vues normales et non modales).

Ceci est un fragment de l'écran dans lequel j'ai essayé le RectButton dans un Modal (essentiellement tel qu'il est dans la mise à jour de la documentation)

  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;
  };

Le modal se charge quand il est censé le faire, mais le RectButton ne déclenche pas l'événement onPress. J'ai essayé de faire une démo minimum reproductible avec une toute nouvelle application, mais je suis ensuite tombé sur # 848 # 676 # 835 (doublons possibles les uns des autres).

whop # 937

C'est incroyable! Cela ne fonctionne toujours pas avec react-native-modal pour moi, cependant!

_ // edit: En fait, le modal par défaut ne fonctionne pas non plus, mais il devrait, à partir de 1.6.0 si je ne me trompe pas ? Essaiera de découvrir ce qui ne va pas_

J'ai joué un peu et j'ai pu trouver le problème. Cependant, je ne sais pas quelle en est la cause ni comment y remédier.

Le problème dans mon cas est que je react-native-gesture-handler ne fonctionnera @react-navigation/stack , s'il est placé dans un modal (donc fondamentalement Stack.Navigator > SomeScreenComponent > Modal > gestureHandlerRootHOC(PanGestureHandler) échoue).

Si je coupe le navigateur de pile ou que j'utilise le navigateur d'onglets à la place, cela fonctionne comme un charme, donc je suis presque sûr que c'est la faute des navigateurs de pile.

Versions de package pertinentes:

[email protected]
@react-navigation/[email protected]
@react-navigation/[email protected]

Je vais essayer de configurer un dépôt de démonstration dès que possible, faites-moi savoir si je peux fournir des informations plus utiles.

Voici une application de démonstration pour (presque vide à partir de npx react-native init ), qui montrera le problème. Vous pouvez basculer le navigateur de pile dans l'application et voir comment le PanGestureHandler devient fonctionnel et non fonctionnel.

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

J'ai un problème similaire. Il semble que Stack.Navigator ne fonctionne pas bien sur Android. Peu importe si j'utilise un mode = "modal" ou "card".

Alors je jouais et j'avais le code suivant

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

}

Ensuite, j'ai supprimé cette ligne;
enableScreens();

Et puis cela a fonctionné correctement sur Android.

Un petit truc pour le résoudre dans un modal:

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

J'ai un problème similaire. Un travail autour?

J'essayais d'utiliser https://github.com/osdnk/react-native-reanimated-bottom-sheet dans un modal, et ce n'est pas possible, j'ai finalement résolu avec une animation d'écran de réaction-navigation:

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

Un petit truc pour le résoudre dans un modal:

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

Salut @gideaoms . Je me demande comment votre commentaire est passé inaperçu ici. Cela fait définitivement l'affaire. Merci mec!

Voici une application de démonstration pour (presque vide à partir de npx react-native init ), qui montrera le problème. Vous pouvez basculer le navigateur de pile dans l'application et voir comment le PanGestureHandler devient fonctionnel et non fonctionnel.

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

alors, quelle est la solution?

J'ai toujours le même problème ...
Une solution ou rien encore?

C'est toujours un problème sur 1.6.0

J'ai essayé toutes les suggestions mentionnées ci-dessus mais toujours pas de chance. S'il vous plaît aider c'est vraiment frustrant.
Ma version native de réaction en 0.62.2 a essayé avec les deux / react-native-gesture-handler 1.5.6 et 1.6.0.

toujours un problème sur ^1.7.0

Ne fonctionne toujours pas: -1:

Nous utilisons wix-navigation. Peut-être quelque chose de lié?

Eh bien, j'ai trouvé une solution de contournement possible, il fait exactement ce que nous voulons et fonctionne à la fois pour iOS et Android.

https://www.youtube.com/watch?v=tLQjGHDiRkM

@steniowagner est-ce comme un modal personnalisé? Je ne le recommanderais pas
il suffit d'utiliser les navigations de réaction ou le modal de la pile native, cela fonctionne très bien.

hmm, je n'ai pas testé avec les navigations de réaction (cela me paraissait trop pour mon cas), mais c'est peut-être la meilleure façon pour le moment.

Merci @ a-eid!

Selon la documentation
https://docs.swmansion.com/react-native-gesture-handler/docs/#usage -with-modals-on-android

mais ne fonctionnait toujours pas pour moi.

@gideaoms que les astuces peuvent fonctionner pour le bouton mais mon cas d'utilisation est d'utiliser PinchGestureHandler dans le modal.

Un petit truc pour le résoudre dans un modal:

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

Ce problème date de plus de 2 ans, est-il prévu de le résoudre?

J'ai créé des composants Slider personnalisés pour mon application et je ne peux pas du tout les utiliser sur Android, car de nombreuses vues de mon application sont des modaux

J'ai enveloppé chaque écran et composant modal dans un gestureHandlerRootHoC (en utilisant wix / react-native-navigation)

J'ai essayé d'encapsuler à la fois l'écran et le composant avec gestureHandlerRootHoc sans succès. Je n'ai pas essayé l'approche RectButton parce que j'ai besoin d'un PanGestureHandler pour implémenter un comportement de balayage vers le bas pour rejeter sur le modal. C'est frustrant car cela fonctionne parfaitement sur iOS et, puisque j'utilise react-native-modal , qui est en fait livré avec glisser pour rejeter hors de la boîte, j'ai même essayé d'utiliser cette approche à la place et cela fonctionne tant que vous n'avez pas de contenu déroulant dans le modal, car il est bogué à la fois sur iOS et Android, donc je suis un peu coincé ...

Pour résumer:

  1. ❌ RNGH ne fonctionne pas dans le composant react-native de <Modal> (même si le composant est enveloppé dans un gestureHandlerRootHOC )
  2. ✅ RNGH fonctionne dans un écran de wix/react-native-navigation qui est affiché en utilisant Navigation.showModal (même si l'écran est enveloppé dans un gestureHandlerRootHOC )
  3. ✅ RNGH fonctionne apparemment s'il est montré en utilisant la fonction push de react-navigation avec modal: true , mais uniquement lorsque vous n'utilisez pas la pile native ( enableScreens() / createNativeStackNavigator() ).

Je peux fournir plus de détails si nécessaire.

react-native-modal-animated fonctionne avec react-native-gesture-handler, car react-native-modal-animated crée un modal en utilisant simplement une vue.

@flyskyPourquoi si -native-modal-animated n'utilise pas une activité distincte comme react-native-modal, alors comment il est rendu par-dessus tout? S'il utilise une position absolue, cela pourrait poser un problème dans certains cas.

@ waheedakhtar694 , il utilise de l'absolu. Au moins dans mon cas, pas de problème: stuck_out_tongue_closed_eyes:

@jvaclavik Je l'ai utilisé en conjonction avec https://github.com/callstack/react-native-paper , qui a un composant appelé Portal conçu spécifiquement à cet effet.

Résolu en utilisant Portal de react -native-paper comme l' @jvaclavik .
J'ai enveloppé mon application avec PaperProvider , puis changé les modaux en vues et les ai enveloppés avec Portal.
Maintenant, la feuille de fond fonctionne sur Android 😍

_EDIT: pour une raison quelconque, les mouvements de panoramique fonctionnent mais les événements onPress ne fonctionnent pas (mais l'ondulation est affichée) ...
EDIT 2: c'était un problème avec la bibliothèque que j'utilisais, je l'ai corrigé en changeant les importations tactiles de "react-native" en "react-native-gesture-handler" _

Voici un code que vous pouvez essayer

/*
 App.js:
 - import { Provider as PaperProvider } from "react-native-paper";
 - wrap your App with PaperProvider
*/

// ModalFixed.js
import { Portal } from 'react-native-paper';
import { gestureHandlerRootHOC } from 'react-native-gesture-handler';

const ModalFixed = (props) => {
  <View style={styles.modal}>
    <View style={styles.shadow} />
    {/* MODAL CONTENT HERE, you can put props.children to reuse this component */}
  </View>
}

const styles = StyleSheet.create({
  modal: {
    width: "100%",
    height: "100%"
  },
  shadow: {
    position: "absolute",
    width: "100%",
    height: "100%",
    backgroundColor: "rgba(0,0,0,0.3)",
  }
})

const _ModalFixed = gestureHandlerRootHOC(SheetPopup)
export default (props) => {
  return (
    <Portal>
      <_ModalFixed {...props} />
    </Portal>
  )
}

Cela fonctionne pour moi:
<TouchableWithoutFeedback onPress={() => { console.log("press"); }} > <Text> <RectButton> ... </RectButton> </Text> </TouchableWithoutFeedback>

Une mise à jour pour ceci? Nous avons deux projets où iOS fonctionne comme prévu mais les modaux Android se révèlent un casse-tête. Nous préférons ne pas avoir à supprimer les modaux des projets ... c'est une grande refonte de la conception. : /

@DavidAPears avez-vous essayé d'encapsuler vos modaux dans gestureHandlerRootHOC ?

quelque chose comme ça ?


const ModalInner = gestureHandlerRootHOC(function GestureExample() {
  return (
    <View>
      { RNGH components . }
    </View>
  );
});

export default function ModalForX() {
  return (
    <Modal animationType="slide" transparent={false}>
      <ModalInner />
    </Modal>
  );
}


La combinaison de Portal de react-native-portalize et gestureHandlerRootHOC fonctionne pour moi. Quelque chose comme ca:

<Portal>
   <Modal>
      <GestureHandlerRootHOCWrappedComponent />
   </Modal>
</Portal>

réglage coverSreen = {false} sur les travaux modaux. Mais j'ai besoin de ma couverture modale de l'écran

importer {Platform, Modal} depuis 'react-native';
import {gestureHandlerRootHOC} depuis 'react-native-gesture-handler';
import {AnimatedBottomSheet} depuis '../AnimatedBottomSheet';

const AnimatedBottomSheetWrapper = Platform.OS === 'android'? gestureHandlerRootHOC (AnimatedBottomSheet): AnimatedBottomSheet;

Je ne sais pas si cela va aider quelqu'un, j'ai également eu des problèmes lors de l'utilisation de cette bibliothèque avec react-native-modal, mais à côté de l'enroulement des enfants de modal gestureHandlerRootHOC (cela fonctionne bien pour les boutons, mais j'ai eu des problèmes avec la saisie de texte en modal + avoidKeyboard = vrai et à chaque pression de touche, le clavier se fermait) Donc, la seule chose que j'ai faite, c'est de créer un wrapper modal pour les enfants, quelque chose comme ceci:

import Modal from 'react-native-modal';
import { gestureHandlerRootHOC } from 'react-native-gesture-handler';

const GestureHandlerWrapper = gestureHandlerRootHOC(
  ({ children }) => <View>{children}</View>,
  { flex: 0 }
);

export const CustomModal: React.FC<Props> = ({
  children,
...rest
}) => {
  return (
    <Modal
      {...rest}
    >
      <GestureHandlerWrapper>    
          {children} 
      </GestureHandlerWrapper>
    </Modal>
  );
};
Cette page vous a été utile?
0 / 5 - 0 notes