React-native-gesture-handler: Не работает в модальном

Созданный на 11 апр. 2018  ·  71Комментарии  ·  Источник: software-mansion/react-native-gesture-handler

Здравствуй !
У меня небольшая проблема с Android: onGestureEvent не запускается, когда компоненты GestureHandler находятся в модальном окне на Android. Когда я меняю модальное окно на View, оно работает отлично 👌

Нет проблем на iOS

Android Bug Can repro Important

Самый полезный комментарий

Небольшой трюк, чтобы решить эту проблему внутри модального окна:

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

Все 71 Комментарий

+1
какой-нибудь обходной путь?

Я пока не использую Modal, я просто воссоздаю его с View в абсолютной позиции

пока использую модальный экран, после поиска в Google и чатов Модальный от RN посчитал слишком много ошибок

+1

Привет, @martinezguillaume , @mordaha , @csto
Я изучал эту проблему и полагаю, что дело не в нашей библиотеке, а в RN Core.

@osdnk это поправимо?

Жест +1 не работает в модальном режиме

Я тоже сегодня столкнулся с этой ошибкой.

Та же проблема. Жест не работает в модальном режиме на Android .
Expo например

Мне то же. Протестировал обработчики PanResponder для реагирования на модальном режиме - работает нормально.

У меня есть мысли по этому поводу: когда мы связываем эту библиотеку с проектом Android, мы делаем следующий шаг

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

И мы знаем, что модальный пакет - это отдельный пакет. Может быть, есть смысл с ним сделать то же самое?

Я использовал стандартный React Native Modal и столкнулся с этой проблемой.
Я решил проблему, создав новый экран и отобразив его как модальный. Я использую response-native-navigation , поэтому:

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

Жесты работают должным образом как на iOS, так и на Android, и я все еще получаю прозрачный фон, который я хотел от моего исходного модального окна.

Некоторое время я копался в этом.

  1. Это проблема RNGH. Извини
  2. Бывает, что модальные окна bc не отображаются ниже корневого представления RN.
  3. Это можно исправить, заменив механизм модальных окон аналогично тому, как мы это делаем с RNRootView, добавив в него дополнительную логику. См. Https://github.com/kmagiera/react-native-gesture-handler/blob/master/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootViewManager.java.
  4. У меня нет времени на это сейчас, это трудоемкая работа и, вероятно, требует копирования некоторого кода в ядре RNGH на собственной стороне Android.

Если кто-то захочет и у меня будет время сделать это, я с радостью рассмотрю его и немедленно объединю, если он будет работоспособным и не слишком взломанным.

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

Кроме того, я попробовал два месяца назад.

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

Может быть, для кого-то это может быть вдохновением 🤷‍♂️

Привет, @osdnk, мне нужна эта функция для моего приложения, поэтому я подумал, что могу попробовать, но у меня нет большого опыта работы с RNGestureHandler или Android. Не могли бы вы дать мне больше информации о том, что мне нужно сделать, чтобы это сработало?
Также я смотрел на вашу предыдущую попытку, и я хотел бы знать, чего не хватает для ее завершения, и можно ли ее использовать в качестве отправной точки.

та же ошибка.

@kmagiera @osdnk есть поводу ?
даже Touchable* не работают внутри модального окна, и это расстраивает

+1. Я использую реанимированный нижний лист с модальным

Любые обновления? Или, возможно, любой другой модальный компонент, который не страдает этой проблемой? Модальный режим RN, честно говоря, работает очень плохо и полон ошибок (например, застревание в сочетании с предупреждением)

@cristianoccazinsp В итоге я использовал https://github.com/react-native-community/react-native-modal

Странный. Предполагается, что этот компонент внутренне использует модальное окно реакции. Сделал это
иметь значение для вас?

Эль июн., 30 мая 2019 г. 14:38, Mars Lan [email protected]
написать:

@cristianoccazinsp https://github.com/cristianoccazinsp Я закончил
используя https://github.com/react-native-community/react-native-modal

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/kmagiera/react-native-gesture-handler/issues/139?email_source=notifications&email_token=ALU263ACF3LNSRSPFWR45ELPYAGJTA5CNFSM4EZ6UZL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODWS7SOQ#issuecomment-497416506 ,
или отключить поток
https://github.com/notifications/unsubscribe-auth/ALU263GRH2KHBXUZBGHNKA3PYAGJTANCNFSM4EZ6UZLQ
.

@cristianoccazinsp Он использует только модальный RN для покрытия экрана, который можно отключить, установив coverScreen на false

@cristianoccazinsp Он использует только модальный RN для покрытия экрана, который можно отключить, установив coverScreen на false

Но есть ли способ показать полноэкранное модальное окно с помощью этой опоры, которая не отображается в корневом компоненте приложения?

@jvaclavik Я использовал его вместе с https://github.com/callstack/react-native-paper , в котором есть компонент Portal, разработанный специально для этой цели.

Это может не разрешить все варианты использования, но вы можете включить жесты в собственном модальном окне, установив для свойства prop propagateSwipe значение true.

Эта проблема, похоже, связана с https://github.com/kmagiera/react-native-screens/issues/61

Не используйте собственные экраны реагирования в Android. Протестировано и отлично работает с reanimated-bottom-sheet

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

Эта модальная конфигурация React Navigation для прозрачного bg

ScreenOne: {
экран: ScreenOne,
navigationOptions: {
gesturesEnabled: false
},
}
{
режим: 'модальный',
transparentCard: правда,
headerMode: 'нет',
cardStyle: {
backgroundColor: 'прозрачный',
непрозрачность: 1
},
transitionConfig: () => ({
containerStyle: {
backgroundColor: 'прозрачный',
}
})
}

@osdnk исправил?

Это было так больно.
Я потратил некоторое время, прежде чем решил погуглить, вытащил волосы, пытаясь понять, почему один и тот же компонент работает на iOS и на Android, но только в некоторых местах внутри приложения

у нас та же проблема - он не работает в модальном режиме.
Интересно, работает ли кто-нибудь над этим или знает ли какое-нибудь обновление статуса?
нам нужно отбросить эту библиотеку и переключиться на обработчики панорамирования RN?
любое предложение ?

Тоже самое. RectButton не работает внутри https://github.com/react-native-community/react-native-modal

@deflorilemarului @ kesha-antonov @fauker
Не сэкономит вам время, ни Modal , ни Modal пакеты (если они не требуют связывания собственных зависимостей - они основаны на react-native 's Modal ) вам поможет (в принципе, я все перепробовал).
Все компоненты, связанные с gesture- (поведение нижнего листа для нас) не будут регистрировать какие-либо касания / смахивания и т. Д. При визуализации внутри <Modal>...</Modal> на android;
Я могу придумать 3 решения:

  1. Используйте любую другую библиотеку, если вы используете модальные окна. Вам может потребоваться переписать некоторые компоненты, основанные на смахивании, на PanResponder ; это больно, но довольно просто;
  2. Используйте модальные окна portals . На самом деле они не являются ни порталами, ни модальными окнами - порталы не поддерживаются в react-native, потому что существует единственный хост приложения - но они работают, размещая Host Component где-то в вашем приложении и визуализируя модальное содержимое в абсолютном виде над стеком приложений; это рабочее решение, но вы потеряете все вызовы useContext() из-за того, что дочерние элементы будут отображаться над поставщиками контекста; у нас не работает, т.к. navigation context теряется;
  3. Используйте модальные окна, предоставляемые библиотекой навигации ( react-navigation ); этот работает, но API ... не подходит - для одного вы не можете сделать один экран модальным, только стек может быть в модальном режиме; это решение, которым я придерживаюсь.

Что ж, есть окончательное решение - патч для собственной реализации Android (невозможно, если вы используете expo) или дождитесь патча в библиотеке, а затем дождитесь, пока он не объединится с expo.

пс
Не поймите меня неправильно, эта библиотека потрясающая, и я не могу не подчеркнуть, насколько я ценю вложенную в нее работу и насколько лучше опыт для конечного пользователя, но такие ошибки заставляют меня выдергивать волосы.

Некоторые библиотеки требуют, чтобы мы имели дело с собственным контекстом, если так:

Для Android нам потребуется особая осторожность, как указано в документе RNGH :

Обновите файл MainActivity.java
Screen Shot 2019-11-30 at 12 17 07 PM

Надеюсь, это поможет

Некоторые библиотеки требуют, чтобы мы имели дело с собственным контекстом, если так:

Для Android нам потребуется особая осторожность, как указано в документе RNGH :

Обновите файл MainActivity.java
Screen Shot 2019-11-30 at 12 17 07 PM

Надеюсь, это поможет

Да, у меня это отлично сработало. Я почти разочаровался в поисках решений, позволяющих сделать мое приложение для Android быстрым.

до сих пор не работает
если изменить модальный режим, чтобы просмотреть все, все работает нормально ...

Привет @romanonthego!

Что ж, есть окончательное решение - патч для собственной реализации Android (невозможно, если вы используете expo) или дождитесь патча в библиотеке, а затем дождитесь, пока он не объединится с expo.

Подскажите, пожалуйста, чем пропатчить мой родной код Android?

@osdnk Это интересно. Будет ли он работать с DialogFragment ?

Попробовав # 937, я обнаружил, что у меня не работает ...

Может быть, это потому, что я использую встроенную навигацию wix? Насколько мне известно, каждый экран регистрируется с помощью gestureHandlerRootHOC (библиотека отлично работает с обычными, немодальными представлениями).

Это фрагмент экрана, на котором я пробовал RectButton в модальном (в основном, как в обновлении документа)

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

Модальное окно загружается тогда, когда должно, но RectButton не запускает событие onPress. Я попытался сделать минимально воспроизводимую демонстрацию с совершенно новым приложением, но затем наткнулся на # 848 # 676 # 835 (возможные дубликаты друг друга).

whop # 937

Это восхитительно! Хотя для меня это все еще не работает с react-native-modal !

_ // edit: Вообще-то модальный режим по умолчанию тоже не работает, но должен, начиная с 1.6.0, если я не ошибаюсь ? Постараюсь выяснить, что не так_

Я немного поигрался и смог найти проблему. Однако я не уверен, в чем причина и как это исправить.

Проблема в моем случае заключается в том, что I react-native-gesture-handler не будет работать внутри @react-navigation/stack , если поместить его внутри модального окна (так что в основном Stack.Navigator > SomeScreenComponent > Modal > gestureHandlerRootHOC(PanGestureHandler) не работает).

Если я вырезал Stack Navigator или вместо него использовал Tab Navigator, он сработает как шарм, поэтому я почти уверен, что это ошибка Stack Navigators.

Соответствующие версии пакета:

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

Я постараюсь настроить демо-репо как можно скорее, дайте мне знать, могу ли я предоставить дополнительную полезную информацию.

Вот демонстрационное приложение (почти пустое от npx react-native init ), которое покажет проблему. Вы можете переключить навигатор стека внутри приложения и увидеть, как PanGestureHandler становится функциональным и нефункциональным.

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

У меня похожая проблема. Похоже, что Stack.Navigator плохо работает на Android. Не имеет значения, использую ли я mode = "modal" или "card".

Итак, я играл и имел следующий код

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

}

Затем я удалил эту строку;
enableScreens();

А потом на Android все заработало.

Небольшой трюк, чтобы решить эту проблему внутри модального окна:

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

У меня аналогичная проблема. Любая работа?

Я пытался использовать https://github.com/osdnk/react-native-reanimated-bottom-sheet внутри модального окна, и это невозможно, я наконец решил с помощью анимации экрана реакции-навигации:

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

Небольшой трюк, чтобы решить эту проблему внутри модального окна:

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

Привет, @gideaoms . Интересно, как ваш комментарий остался здесь незамеченным. Это определенно помогает. Спасибо чувак!

Вот демонстрационное приложение (почти пустое от npx react-native init ), которое покажет проблему. Вы можете переключить навигатор стека внутри приложения и увидеть, как PanGestureHandler становится функциональным и нефункциональным.

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

тогда какое решение?

У меня все еще та же проблема ....
Любое решение или еще ничего?

Это все еще проблема в 1.6.0

Пробовал все предложения, упомянутые выше, но все равно не повезло. Пожалуйста, помогите, это действительно расстраивает.
Моя собственная версия реакции в 0.62.2 пробовала использовать оба / response-native-gesture-handler 1.5.6 и 1.6.0.

все еще проблема с ^1.7.0

Все еще не работает: -1:

Мы используем wix-навигацию. Может что-то связанное?

Что ж, я нашел возможный обходной путь, он делает именно то, что мы хотим, и работает как для iOS, так и для Android.

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

@steniowagner это похоже на настраиваемый модальный? Я бы не рекомендовал это
просто используйте реагирующую навигацию или модальный собственный стек, он отлично с этим работает.

хм, не тестировал с помощью реакции-навигации (звучало слишком много для моего случая), но, возможно, это лучший способ на данный момент.

Спасибо @ a-eid!

Согласно документам
https://docs.swmansion.com/react-native-gesture-handler/docs/#usage -with-modals-on-android

но все равно у меня не работало.

@gideaoms, что уловки могут работать для кнопки, но мой вариант использования - использовать PinchGestureHandler внутри модального окна.

Небольшой трюк, чтобы решить эту проблему внутри модального окна:

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

Этой проблеме больше двух лет, есть ли планы ее исправить?

Я создал пользовательские компоненты Slider для своего приложения и вообще не могу их использовать на Android, так как многие представления в моем приложении являются модальными.

Я обернул каждый экран и модальный компонент в gestureHandlerRootHoC (используя wix / react-native-navigation)

Я безуспешно пытался обернуть экран и компонент gestureHandlerRootHoc . Я не пробовал подход RectButton потому что мне нужен PanGestureHandler , чтобы реализовать в модальном окне поведение "смахнуть вниз, чтобы закрыть". Это расстраивает, потому что он отлично работает на iOS, и, поскольку я использую react-native-modal , который на самом деле поставляется со встроенной функцией swipe-to-dismiss, я даже попытался использовать этот подход вместо этого и он работает до тех пор, пока у вас нет прокручиваемого контента внутри модального окна, потому что тогда он глючит как на iOS, так и на Android, поэтому я как бы застрял ...

Подводить итоги:

  1. ❌ RNGH не работает в react-native компоненте <Modal> (даже если компонент заключен в gestureHandlerRootHOC )
  2. ✅ RNGH действительно работает на экране из wix/react-native-navigation , который отображается с использованием Navigation.showModal (даже если экран заключен в gestureHandlerRootHOC )
  3. ✅ RNGH, по-видимому, работает, если показано с использованием функции push react-navigation с modal: true , но только когда не используется собственный стек ( enableScreens() / createNativeStackNavigator() ).

При необходимости я могу предоставить более подробную информацию.

response-native-modal-animated работает с response-native-gesture-handler, потому что react-native-modal-animated создает модальное окно только с помощью представления.

@flyskywhy, если -native-modal-animated не использует отдельное действие, такое как react-native-modal, тогда как он отображается поверх всего? Если он использует абсолютное положение, в некоторых случаях это может создать проблему.

@ waheedakhtar694 , он использует абсолют. По крайней мере, в моем случае проблем нет: stuck_out_tongue_closed_eyes:

@jvaclavik Я использовал его вместе с https://github.com/callstack/react-native-paper , в котором есть компонент Portal, разработанный специально для этой цели.

Решено с использованием Portal из response -native-paper, как сказал
Я обернул свое приложение PaperProvider , затем изменил Modals на Views и обернул их с помощью gestureHandlerRootHOC и Portal.
Теперь нижний лист работает на Android 😍

_EDIT: по какой-то причине жесты панорамирования работают, но события onPress не работают (но отображается рябь) ...
РЕДАКТИРОВАТЬ 2: это была проблема с библиотекой, которую я использовал, я исправил ее, изменив сенсорный импорт с «react-native» на «react-native-gesture-handler» _

Вот код, который вы можете попробовать

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

Это работает для меня:
<TouchableWithoutFeedback onPress={() => { console.log("press"); }} > <Text> <RectButton> ... </RectButton> </Text> </TouchableWithoutFeedback>

Есть новости по этому поводу? У нас есть два проекта, в которых iOS работает, как и ожидалось, но модальные окна Android вызывают головную боль. Мы бы предпочли не удалять модальные окна из проектов ... это серьезная переработка дизайна. : /

@DavidAPears вы пробовали обернуть свои модальные окна в gestureHandlerRootHOC ?

что-то вроде этого ?


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

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


Комбинация Portal из react-native-portalize и gestureHandlerRootHOC у меня работает. Что-то подобное:

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

установка coverSreen = {false} для модальных работ. Но мне нужна моя модальная крышка экрана

импортировать {Platform, Modal} из 'react-native';
импортировать {gestureHandlerRootHOC} из обработчика собственных жестов;
импортировать {AnimatedBottomSheet} из '../AnimatedBottomSheet';

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

Не уверен, что это поможет кому-то, у меня также были проблемы с использованием этой библиотеки с response-native-modal, но помимо обертывания дочерних элементов модального gestureHandlerRootHOC (это отлично работает для кнопок, но у меня были проблемы с вводом текста в модальном + escapeKeyboard = true и при каждом нажатии клавиши клавиатура закрывалась) Итак, единственное, что я сделал, - это модальная дочерняя оболочка, примерно так:

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>
  );
};
Была ли эта страница полезной?
0 / 5 - 0 рейтинги