React-native-gesture-handler: Não funciona em modal

Criado em 11 abr. 2018  ·  71Comentários  ·  Fonte: software-mansion/react-native-gesture-handler

Oi !
Eu tenho um pequeno problema no Android, onGestureEvent não é acionado quando os componentes do GestureHandler estão em um modal no Android. Quando eu mudo o modal para uma visualização, funciona perfeitamente 👌

Sem problemas no iOS

Android Bug Can repro Important

Comentários muito úteis

Um pequeno truque para resolver dentro de um modal:

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

Todos 71 comentários

+1
alguma solução alternativa?

Não uso o Modal por enquanto, apenas o recrio com uma View em posição absoluta

usando tela modal por enquanto, depois de pesquisar e chats Modal da RN considerou muita coisa bugada

+1

Olá, @martinezguillaume , @mordaha , @csto
Dei uma olhada neste problema e suponho que não seja uma questão de nossa biblioteca, mas RN Core.

@osdnk isso corrigido ?

O gesto de +1 não funciona no modal

Eu também encontrei esse bug hoje.

Mesmo problema. O gesto não funciona em modal no Android .
Expo por exemplo

O mesmo para mim. Manipuladores do PanResponder do react-native testado no modal - funciona bem.

Eu tenho uma ideia sobre isso: quando estamos vinculando esta biblioteca ao projeto android, estamos dando o próximo passo

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

E sabemos que modal é um pacote separado. Pode haver sentido em fazer algo igual com ele?

Eu estava usando um React Native Modal padrão e estava tendo esse problema.
Eu contornei o problema criando uma nova tela e exibindo-a como modal. Estou usando a navegação react-nativa , então:

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

Os gestos estão funcionando como esperado no iOS e no Android, e ainda recebo o fundo transparente que queria do meu modal original.

Eu cavei nisso por um tempo.

  1. É um problema de RNGH. Desculpa 😒
  2. Acontece que os modais bc não são renderizados abaixo de uma visualização de raiz RN.
  3. É corrigível substituindo o mecanismo dos modais de uma forma semelhante à que fazemos com um RNRootView, envolvendo-o com alguma lógica extra. Consulte https://github.com/kmagiera/react-native-gesture-handler/blob/master/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootViewManager.java
  4. Não tenho tempo para fazer isso agora, é um trabalho demorado e provavelmente requer a cópia de algum código em um núcleo RNGH no lado nativo do Android.

Se alguém quiser e tiver tempo para fazer isso, ficarei feliz em revisá-lo e mesclar imediatamente se for viável e não muito hacky.

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

Além disso, fiz uma tentativa há dois meses.

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

Talvez possa ser uma inspiração para alguém 🤷‍♂️

Ei @osdnk , preciso desse recurso para meu aplicativo, então pensei em tentar, mas não tenho muita experiência com RNGestureHandler ou Android. Você poderia me dar mais informações sobre o que eu preciso fazer para que funcione?
Também estava olhando sua tentativa anterior e gostaria de saber o que falta para que ela seja concluída e se ela poderia ser usada como ponto de partida.

mesmo erro.

@kmagiera @osdnk alguma atualização sobre isso?
mesmo Touchable* não funcionam dentro do modal e isso é frustrante

+1. eu uso folha inferior reanimada com modal

Alguma atualização? Ou talvez, algum outro componente modal que não sofra com esse problema? O modal da RN honestamente funciona como muito ruim e está cheio de bugs (como travar se combinado com um alerta)

Ímpar. Esse componente deve usar o modal de react internamente. Fez isso
faz diferença para você?

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

@cristianoccazinsp https://github.com/cristianoccazinsp acabei
usando https://github.com/react-native-community/react-native-modal

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/kmagiera/react-native-gesture-handler/issues/139?email_source=notifications&email_token=ALU263ACF3LNSRSPFWR45ELPYAGJTA5CNFSM4EZ6UZL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODWS7SOQ#issuecomment-497416506 ,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/ALU263GRH2KHBXUZBGHNKA3PYAGJTANCNFSM4EZ6UZLQ
.

@cristianoccazinsp Só usa modal de RN para cobrir a tela, que pode ser desabilitada configurando coverScreen para false

@cristianoccazinsp Só usa modal de RN para cobrir a tela, que pode ser desabilitada configurando coverScreen para false

Mas existe uma maneira de mostrar modal em tela cheia com este prop que não é renderizado no componente raiz do aplicativo?

@jvaclavik Usei-o em conjunto com https://github.com/callstack/react-native-paper , que tem um componente chamado Portal projetado especificamente para esse fim.

Isso pode não resolver todos os casos de uso, mas você pode habilitar gestos no modal nativo de reação ao definir o prop propagateSwipe como verdadeiro.

Este problema parece estar relacionado a https://github.com/kmagiera/react-native-screens/issues/61

Não use telas nativas Rea no Android. Testado e funcionando bem com 'folha inferior reanimada'

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

Esta configuração do Modal de navegação React para bg transparente é

ScreenOne: {
tela: ScreenOne,
NavigationOptions: {
gesturesEnabled: false
},
}
{
modo: 'modal',
transparentCard: verdadeiro,
headerMode: 'none',
cardStyle: {
backgroundColor: 'transparente',
opacidade: 1
},
TransiçãoConfig: () => ({
containerStyle: {
backgroundColor: 'transparente',
}
})
}

@osdnk corrigiu isso?

Este aqui foi muito doloroso.
Eu gastei algum tempo antes de resolver pesquisar no Google, tentar descobrir por que diabos o mesmo componente funciona no iOS e no Android, mas apenas em alguns lugares dentro do aplicativo

temos o mesmo problema - não funciona no modal.
Gostaria de saber se alguém está trabalhando nisso ou sabe de alguma atualização de status?
precisamos descartar esta biblioteca e mudar para manipuladores de pan RN?
alguma sugestão ?

O mesmo aqui. RectButton não funciona dentro de https://github.com/react-native-community/react-native-modal

@deflorilemarului @ kesha-antonov @fauker
Irá poupar-lhe algum tempo, nem Modal , nem pacotes baseados em Modal (se eles não exigirem que você vincule dependências nativas - eles são baseados em react-native 's Modal ) irá ajudá-lo (eu tentei todos eles, basicamente).
Todos os componentes relacionados a gesture- (comportamento de folha de fundo para nós) não registrarão nenhum toque / deslize etc quando renderizados dentro de <Modal>...</Modal> no android;
Posso pensar em 3 soluções:

  1. Use qualquer outra biblioteca se estiver usando modais. Você pode exigir a reescrita de alguns componentes baseados em furto para PanResponder ; isso é doloroso, mas bastante direto;
  2. Use modais que sejam portals . Eles não são realmente portais nem modais - os portais não são suportados pelo react-native porque há um único host de aplicativo - mas eles estão trabalhando colocando o componente Host em algum lugar no seu aplicativo e renderizando o conteúdo Modal em visualização absoluta acima da pilha do aplicativo; esta é uma solução funcional, mas você perderá quaisquer chamadas useContext() devido aos filhos serem renderizados acima dos provedores de contexto; não funciona para nós, uma vez que o contexto navigation foi perdido;
  3. Use modais fornecidos pela biblioteca de navegação ( react-navigation ); este funciona, mas API é ... não é bom - para um você não poderia transformar uma única tela em modal, apenas uma pilha pode estar em modo modal; esta é a solução com a qual continuo.

Bem, há uma solução final - corrigir a implementação nativa do Android (não é possível se você estiver usando o expo) ou esperar pelo patch em uma biblioteca e depois esperar até que ele se mesclasse ao expo.

ps
Não me interpretem mal, esta biblioteca é incrível, e eu não posso enfatizar o quanto eu aprecio o trabalho que está sendo colocado nela e como a experiência é muito melhor para o usuário final, mas bugs como este me dão vontade de arrancar meus cabelos.

Poucas bibliotecas exigem que lidemos com contexto nativo, se assim for:

Para o Android, precisaremos de um cuidado especial conforme declarado no documento RNGH :

Atualize seu arquivo MainActivity.java
Screen Shot 2019-11-30 at 12 17 07 PM

Espero que ajude

Poucas bibliotecas exigem que lidemos com contexto nativo, se assim for:

Para o Android, precisaremos de um cuidado especial conforme declarado no documento RNGH :

Atualize seu arquivo MainActivity.java
Screen Shot 2019-11-30 at 12 17 07 PM

Espero que ajude

Sim, funcionou perfeitamente para mim. Quase fiquei frustrado procurando soluções para tornar meu aplicativo Android swippable.

Ainda não funciona
se mudar modal para ver tudo funcionar bem ...

Olá @romanonthego ,

Bem, há uma solução final - corrigir a implementação nativa do Android (não é possível se você estiver usando o expo) ou esperar pelo patch em uma biblioteca e depois esperar até que ele se mesclasse ao expo.

Você pode me dizer o que corrigir no meu código android nativo?

@osdnk Isso é emocionante. Também funcionará com DialogFragment ?

Depois de tentar # 937, descobri que não funcionava para mim ...

Talvez seja porque eu estou usando a navegação react-nativa do wix? Pelo que eu sei, cada tela é registrada com o gestoHandlerRootHOC (a biblioteca funciona perfeitamente com visualizações normais e não modais).

Este é um fragmento da tela em que experimentei o RectButton em um Modal (basicamente como está na atualização do doc)

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

O modal é carregado quando deveria, mas o RectButton não dispara o evento onPress. Tentei fazer uma demonstração reproduzível mínima com um aplicativo totalmente novo, mas depois encontrei o # 848 # 676 # 835 (possíveis duplicatas um do outro).

whop # 937

Isso é incrível! Ele ainda não funciona com react-native-modal para mim, no entanto!

_ // editar: Na verdade, o modal padrão também não funciona, mas deveria, a partir de 1.6.0, se não me engano ? Vou tentar descobrir o que está acontecendo de errado_

Eu brinquei um pouco e consegui encontrar o problema. No entanto, não tenho certeza do que está causando isso e como corrigi-lo.

O problema no meu caso é que eu react-native-gesture-handler não funcionarei dentro de um @react-navigation/stack , se colocado dentro de um modal (então basicamente Stack.Navigator > SomeScreenComponent > Modal > gestureHandlerRootHOC(PanGestureHandler) falha).

Se eu cortar o Stack Navigator ou usar o Tab Navigator em vez disso, ele funcionará perfeitamente, então tenho certeza de que a culpa é dos Stack Navigators.

Versões de pacote relevantes:

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

Vou tentar configurar um repositório de demonstração o mais rápido possível. Avise-me se puder fornecer mais informações úteis.

Aqui está um aplicativo de demonstração para (quase em branco de npx react-native init ), que mostrará o problema. Você pode alternar o navegador de pilha dentro do aplicativo e ver como PanGestureHandler se torna funcional e não funcional.

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

Eu tenho um problema semelhante. Parece que o Stack.Navigator não funciona bem no Android. Não importa se eu uso um modo = "modal" ou "cartão".

Então, eu estava brincando e tinha o seguinte código

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

}

Então eu removi esta linha;
enableScreens();

E então funcionou corretamente no Android.

Um pequeno truque para resolver dentro de um modal:

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

Estou tendo um problema semelhante. Alguma solução?

Eu estava tentando usar https://github.com/osdnk/react-native-reanimated-bottom-sheet dentro de um modal e não é possível, finalmente resolvi com a animação da tela de navegação reativa:

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

Um pequeno truque para resolver dentro de um modal:

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

Ei @gideaoms . Eu me pergunto como seu comentário passou despercebido aqui. Definitivamente funciona. Obrigado cara!

Aqui está um aplicativo de demonstração para (quase em branco de npx react-native init ), que mostrará o problema. Você pode alternar o navegador de pilha dentro do aplicativo e ver como PanGestureHandler se torna funcional e não funcional.

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

então, qual é a solução?

Ainda estou tendo o mesmo problema ....
Alguma solução ou nada ainda?

Isso ainda é um problema no 1.6.0

Tentei todas as sugestões mencionadas acima, mas ainda sem sorte. Por favor, ajude, é realmente frustrante.
Minha versão nativa do react em 0.62.2 tentou com ambos / react-native-Gesture Handler 1.5.6 e 1.6.0.

ainda é um problema em ^1.7.0

Ainda não está funcionando: -1:

Usamos navegação wix. Talvez algo relacionado?

Bem, eu encontrei uma solução possível, ele faz exatamente o que queremos e funciona para iOS e Android.

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

@steniowagner isso é como um modal personalizado? Eu não recomendaria
basta ir com navegações de reação ou modal de pilha nativa, ele funciona bem.

hmm, não testei com navegações de reação (parecia demais para o meu caso), mas talvez seja a melhor maneira no momento.

Obrigado @ a-eid!

De acordo com os docs
https://docs.swmansion.com/react-native-gesture-handler/docs/#usage -with-modals-on-android

mas ainda não funcionou para mim.

@gideaoms que truques podem funcionar para o botão, mas meu caso de uso é usar PinchGestureHandler dentro do modal.

Um pequeno truque para resolver dentro de um modal:

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

Este problema tem mais de 2 anos. Existem planos para corrigir isso?

Eu criei componentes Slider personalizados para meu aplicativo e não posso usá-los de jeito nenhum no Android, já que muitas visualizações em meu aplicativo são modais

Eu envolvi cada tela e componente modal em um gestureHandlerRootHoC (usando wix / react-native-navigation)

Tentei envolver a tela e o componente com gestureHandlerRootHoc sem sucesso. Não tentei a abordagem RectButton porque preciso de um PanGestureHandler para implementar o comportamento deslizar para baixo para dispensar no modal. É frustrante porque funciona perfeitamente no iOS e, como estou usando react-native-modal , que na verdade vem com deslizar para dispensar pronto para uso, até tentei usar essa abordagem e funciona contanto que você não tenha conteúdo rolável dentro do modal, porque há bugs no iOS e no Android, então estou meio preso ...

Resumindo:

  1. ❌ RNGH não funciona no react-native 's <Modal> componente (mesmo que o componente é envolto em um gestureHandlerRootHOC )
  2. ✅ RNGH funciona em uma tela de wix/react-native-navigation , que é mostrada usando Navigation.showModal (mesmo que a Tela esteja envolvida em gestureHandlerRootHOC )
  3. ✅ RNGH aparentemente funciona se mostrado usando a função push de react-navigation com modal: true , mas apenas quando não estiver usando a pilha nativa ( enableScreens() / createNativeStackNavigator() ).

Posso fornecer mais detalhes, se necessário.

Reagir nativo-modal-animado funciona com react-nativo-gestual-manipulador, porque react-nativo-modal-animado criando um Modal apenas usando uma Visualização.

@flyskywhy se o -native-modal-animated não usar uma atividade separada como o react-native-modal, então como é renderizado em cima de tudo? Se estiver usando uma posição absoluta, pode ser um problema em alguns casos.

@ waheedakhtar694 , está usando absoluto. Pelo menos no meu caso, sem problema: stick_out_tongue_closed_eyes:

@jvaclavik Usei-o em conjunto com https://github.com/callstack/react-native-paper , que tem um componente chamado Portal projetado especificamente para esse fim.

Resolvido usando o Portal do react -native-paper como
Eu envolvi meu aplicativo com PaperProvider , então mudei Modals para Views e os envolvi com gestHandlerRootHOC e Portal.
Agora a página inferior funciona no Android 😍

_EDIT: por algum motivo, os gestos panorâmicos estão funcionando, mas os eventos onPress não estão funcionando (mas o ripple é mostrado) ...
EDIT 2: esse era um problema com a biblioteca que usei, resolvi mudar as importações tocáveis ​​de "react-nativa" para "react-nativa-gestual-manipulador" _

Aqui está um código que você pode tentar

/*
 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>
  )
}

Está funcionando para mim:
<TouchableWithoutFeedback onPress={() => { console.log("press"); }} > <Text> <RectButton> ... </RectButton> </Text> </TouchableWithoutFeedback>

alguma atualização disso? Temos dois projetos em que o iOS está funcionando conforme o esperado, mas os modais Android estão sendo uma dor de cabeça. Preferimos não ter que remover modais dos projetos ... é uma grande reformulação do design. : /

@DavidAPears você tentou envolver seus modais em gestureHandlerRootHOC ?

algo assim ?


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

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


A combinação de Portal de react-native-portalize e gestureHandlerRootHOC funciona para mim. Algo parecido:

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

definindo coverSreen = {false} em trabalhos modais. Mas preciso que meu modal cubra a tela

import {Platform, Modal} from 'react-native';
importar {gestoHandlerRootHOC} de 'react-native-gesto-handler';
importar {AnimatedBottomSheet} de '../AnimatedBottomSheet';

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

Não tenho certeza se isso vai ajudar alguém, eu também tive problemas ao usar esta biblioteca com react-native-modal, mas além de envolver os filhos do modal gestureHandlerRootHOC (isso está funcionando bem para botões, mas eu tive problemas com a entrada de texto no modal + AvoidKeyboard = verdadeiro e, a cada pressionamento de tecla, o teclado fechava) Então, a única coisa que eu fiz foi fazer um wrapper modal infantil, algo assim:

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>
  );
};
Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

Agoujil2saad picture Agoujil2saad  ·  3Comentários

rgangopadhya picture rgangopadhya  ·  4Comentários

neiker picture neiker  ·  3Comentários

tallen11 picture tallen11  ·  3Comentários

brentvatne picture brentvatne  ·  5Comentários