1

I created a native Modal using Gesture from react-native-gesture-handler so that the Modal can be closed by swiping down. In iOS, after closing the mode and switching to other screens, the app hangs/closes or needs to be restarted. There is no error in the console, but there is a message in Xcode that the application has stopped.

It looks like it happens when I use the new architecture RCT_NEW_ARCH_ENABLED=1, if disable then it works well

"react-native": "0.74.3",
"react-native-gesture-handler": "^2.18.1",
"react-native-reanimated": "^3.14.0",
"react-native-safe-area-context": "^4.10.7",
"react-native-screens": "^3.32.0",

code error 1

code error 2

Root App.tsx

import 'react-native-gesture-handler';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import RootNavigator from './navigation/RootNavigator/RootNavigator';

const App: FC = () => (
  <ThemeProvider>
    <LocaleProvider>
      <GestureHandlerRootView style={{ flex: 1 }}>
        <SafeAreaProvider>
          <RootNavigator />
        </SafeAreaProvider>
      </GestureHandlerRootView>
    </LocaleProvider>
  </ThemeProvider>
);

export default App;

CustomModal.tsx

import { PropsWithChildren, useRef } from 'react';
import {
  Modal,
  Dimensions,
  ModalProps,
  View,
  StyleProp,
  ViewStyle,
  Platform,
  SafeAreaView,
  Text
} from 'react-native';
import {
  ScrollView,
  GestureHandlerRootView,
  GestureDetector,
  Gesture,
  GestureType,
} from 'react-native-gesture-handler';
import { runOnJS, useSharedValue, withSpring } from 'react-native-reanimated';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useTheme } from '../../theme';

interface I Modal extends ModalProps {
  onClose: () => void;
  headerTitle?: string;
  scrollEnabled?: boolean;
}

const { height: windowHeight } = Dimensions.get('window');

export function CustomModal({
  children,
  onClose,
  headerTitle,
  scrollEnabled,
  ...props
}: PropsWithChildren<IModal>) {
  const { layout, gutters, colors, borders, fonts, navigationTheme } =
    useTheme();
  const translateY = useSharedValue(0);
  const insets = useSafeAreaInsets();

  const simultaneousRef = useRef<GestureType | undefined>(undefined);
  const scrollViewRef = useRef<ScrollView | null>(null);

  const panGesture = Gesture.Pan()
    .onUpdate((event) => {
      translateY.value = event.translationY;
    })
    .onEnd((event) => {
      if (event.translationY > windowHeight / 4) {
        runOnJS(onClose)();
      } else {
        translateY.value = withSpring(0);
      }
    })
    .simultaneousWithExternalGesture(scrollViewRef)
    .withRef(simultaneousRef);

  const contentContainerStyle: ViewStyle[] = [
    layout.flexGrow_1,
    gutters.paddingHorizontal_16,
  ];

  return (
    <Modal
      animationType="slide"
      onRequestClose={onClose}
      presentationStyle="pageSheet"
      transparent={false}
      {...props}
    >
      <GestureHandlerRootView style={[layout.flex_1]}>
        <SafeAreaView style={[layout.flex_1]}>
          <GestureDetector gesture={panGesture}>
            <View
              style={[
                layout.fullHeight,
                layout.fullWidth,
                gutters.paddingTop_10,
              ]}
            >
              <View
                style={[
                  layout.row,
                  layout.itemsCenter,
                  layout.justifyBetween,
                  gutters.paddingVertical_16,
                ]}
              >
                <View style={[layout.flex_1]}>
                  <Text
                    numberOfLines={1}
                    style={[fonts.center, fonts.size_18, fonts.lineHeight_22]}
                  >
                    {headerTitle}
                  </Text>
                </View>
                <View style={[layout.flex_05, gutters.marginLeft_4]} />
              </View>
              <ScrollView
                ref={scrollViewRef}
                contentContainerStyle={contentContainerStyle}
                keyboardDismissMode="on-drag"
                keyboardShouldPersistTaps="handled"
                nestedScrollEnabled
                scrollEnabled={scrollEnabled}
                simultaneousHandlers={simultaneousRef}
              >
                {children}
              </ScrollView>
            </View>
          </GestureDetector>
        </SafeAreaView>
      </GestureHandlerRootView>
    </Modal>
  );
}

Podfile:

# Resolve react_native_pods.rb with node to allow for hoisting
require Pod::Executable.execute_command('node', ['-p',
  'require.resolve(
    "react-native/scripts/react_native_pods.rb",
    {paths: [process.argv[1]]},
  )', __dir__]).strip

platform :ios, min_ios_version_supported
prepare_react_native_project!

linkage = ENV['USE_FRAMEWORKS']
if linkage != nil
  Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
  use_frameworks! :linkage => linkage.to_sym
end

target 'Awesome' do
  config = use_native_modules!

  use_react_native!(
    :path => config[:reactNativePath],
    # An absolute path to your application root.
    :app_path => "#{Pod::Config.instance.installation_root}/.."
  )

  target 'AwesomeTests' do
    inherit! :complete
    # Pods for testing
  end

  post_install do |installer|
    # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
    react_native_post_install(
      installer,
      config[:reactNativePath],
      :mac_catalyst_enabled => false,
      # :ccache_enabled => true
    )
  end
end

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.