javascriptreact-nativereact-navigation-v5react-animatedreact-native-reanimated

React Navigation, How To Place Screens Top On Each Other


I want to achieve a screen like below image.

enter image description here

I have this transition:

const MyTransition = {
  transitionSpec: {
    open: {
      animation: 'timing',
      config: {
        duration: 750,
      },
    },
    close: {
      animation: 'timing',
      config: {
        duration: 750,
      },
    },
  },
  cardStyleInterpolator: ({ current, next, layouts }) => {
    return {
      cardStyle: {
        transform: [
          {
            perspective: 750
          },
          {
            translateY: current.progress.interpolate({
              inputRange: [0,  1],
              outputRange: [height -54,  54],
            }),
          },
          {
            scale: current.progress.interpolate({
              inputRange: [0, 1, 2],
              outputRange: [1.2, 1, .9],
            }),
          },
    
        ],
      },
      overlayStyle: {
        opacity: current.progress.interpolate({
          inputRange: [0, 1],
          outputRange: [0, 1],
        }),
      },
    }
  },
}

Navigator:

<Stack.Navigator
  screenOptions={{
    headerShown: false,
    cardOverlayEnabled: true,
    gestureEnabled: true,
    ...MyTransition,
  }}
>
  <Stack.Screen name="ScreenA" component={ScreenA} />
  <Stack.Screen name="ScreenB" component={ScreenB} mode='modal'/>
</Stack.Navigator>

Please see the transition animation here with Loom video

(BTW, can I embed gif/Loom video into question?)

As you can see from the video,

-Screen A has unnessessray top empty space.

-Screen A and Screen B doesn't have top border radius.

(If I use borderRadius, I got this error: Property 'borderRadius' is not supported by native animated module)

-After Screen B opened, cannot see the Screen A under the Screen B.

How can I solve the above issues?

Edit: In case Loom video doesn't open, I am adding images.

enter image description here

enter image description here


Solution

  • For React Navigation 6:

    <Stack.Navigator
      screenOptions={{
        presentation: "modal",
        gestureEnabled: true,
      }}
    >
      <Stack.Screen name="Home" component={Home} />
      <Stack.Screen name="Profile" component={Profile} />
    </Stack.Navigator>
    

    https://reactnavigation.org/docs/stack-navigator#presentation

    For React Navigation 5:

    import { TransitionPresets } from "@react-navigation/stack";
    
    // ...
    
    <Stack.Navigator
      mode="modal"
      screenOptions={({ route, navigation }) => ({
        gestureEnabled: true,
        cardOverlayEnabled: true,
        headerStatusBarHeight:
          navigation.getState().routes.findIndex(r => r.key === route.key) > 0
            ? 0
            : undefined,
        ...TransitionPresets.ModalPresentationIOS
      })}
    >
      <Stack.Screen name="Home" component={Home} />
      <Stack.Screen name="Profile" component={Profile} />
    </Stack.Navigator>;
    

    https://reactnavigation.org/docs/5.x/stack-navigator#pre-made-configs