Cam Tullos
Cam Tullos

Reputation: 2577

React Navigation: Force screen to animate from left to right

With React Navigation v6.x and using the .navigate() function, new views always animate from right to left.

Typically this is fine, but I have a couple views that I always want to load from the left.

I have tried to read the docs, code examples, and stackoverflow threads related to transitions and I cannot glean any useful information.

Can anyone can give me some pointers on this?

Cheers

Upvotes: 6

Views: 17148

Answers (6)

Uch
Uch

Reputation: 244

The other answers did not work for me because slide_from_right only works on Android. I have a cross platform app. The way I solved this was by using route params in the Stack Navigator.

In my StackParamList, I set a mandatory fromLocation param.

export type SomeStackParamList = {
 SomeStack: {
    randomField1: string;
    fromLocation: "home" | "chatscreen";
    newlyAddedNote?: string; // passing a string so it will register as changed every time
  };
}

Let's say I want navigations to the chatScreen to Slide in from left to right.

<SomeNavStack.Navigator // this is just to show the screen should be inside of a stack navigator
      initialRouteName="home"
      screenOptions={({ navigation, route }) => ({
        headerStyle: [
          styles.navHeaderStyle,
        ]
    ..... // you should copy the code below
 <PlaylistNavStack.Screen
        name="PlaylistContent"
        // @ts-ignore

        component={PlaylistContentScreen}
        options={({ navigation, route }) => ({
          gestureDirection:
            route.params.fromLocation === "home"
              ? "horizontal"
              : route.params.fromLocation === "chatScreen"
              ? "horizontal-inverted"
              : "horizontal", // I keep this third option in case I add more possible values in the future
          headerTitle: "Some Screen",
        })}
      />

Keep in mind, this example is on the options of a screen not a navigator. You can do the same think on the screenOptions of a navigator.

Upvotes: 0

Zulfikar Ahmad
Zulfikar Ahmad

Reputation: 504

for stack navigator, we can use CardStyleInterpolators. documentation

...    
options={{
     cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS
}}

Upvotes: 0

julziemoon
julziemoon

Reputation: 156

2023 solution

You can define the direction by setting the "gestureDirection" option.

For Stack.Navigator:

      <Stack.Navigator
        screenOptions={{
          gestureDirection: "horizontal-inverted"}
        }}
      ></Stack.Navigator>

For Stack.Screen:

      <Stack.Screen
        options={{
          gestureDirection: "horizontal-inverted"}
        }}
      ></Stack.Screen>

Upvotes: 2

Jacobo Mata
Jacobo Mata

Reputation: 41

It depends on the Navigator

For Stack Navigator

Use gestureDirection: 'horizontal-inverted'. An example:

    <Stack.Navigator
      screenOptions={{
        gestureDirection: 'horizontal-inverted',
      }}
    >
      <Stack.Screen name="Login" component={Login} />
      <Stack.Screen name="Register" component={Register} />
    </Stack.Navigator>

For Native Stack Navigator

Use animation: 'slide_from_right'

<Stack.Navigator>
  <Stack.Screen
    name="Home"
    component={HomeScreen}
    options={{animation: 'slide_from_right'}}
  />
  <Stack.Screen
    name="Profile"
    component={ProfileScreen}
    options={{animation: 'slide_from_right'}}
  />
</Stack.Navigator>

Upvotes: 4

Kir Fon
Kir Fon

Reputation: 21

Set options

animation: 'slide_from_right'

https://reactnavigation.org/docs/native-stack-navigator/#options

Upvotes: 1

carlosdafield
carlosdafield

Reputation: 1537

First make this below.

 const leftToRightAnimation = {
  cardStyleInterpolator: ({ current, layouts }) => {
    return {
      cardStyle: {
        transform: [
          {
            translateX: current.progress.interpolate({
              inputRange: [0, 1],
              outputRange: [-layouts.screen.width, 0],
            }),
          },
        ],
      },
    };
  },
};

Basically all it's doing is it's moving the screen from the x direction of full screen width away in left direction to fitting the screen. And implicitly progress is going from 0 to 1.

Then put it in the screen you want the transition to apply to.

<NavigationContainer>
      <Root.Navigator headerMode="none" initialRouteName="Home">
        <Root.Screen name="Home" component={Home} />
        <Root.Screen name="NotModal" component={NotModal} options={leftToRightAnimation} />
      </Root.Navigator>
 </NavigationContainer>

Upvotes: 3

Related Questions