In my app I have three screens: ScreenA
, ScreenB
and ScreenC
. They all should have a header and they should all have a back button with the name of the previous screen. I wanted ScreenA
to be able to open ScreenB
using the modal animation:
const ModalStack = createStackNavigator(
{
ScreenA,
ScreenB
},
{
initialRouteName: "ScreenA",
mode: "modal"
}
);
And ScreenA
should also be able to open ScreenC
using the default sliding animation from right to left. The problem was, that the StackNavigator was already configured with the modal mode. Is there a way to dynamically set the mode? So that from ScreenA
to ScreenB
modal is used and from ScreenA
to ScreenC
card?
Furthermore how to handle the header in this case? (For the reason why I ask this question, please read further.)
Here is what I tried after reading the documentation. It describes a similar scenario.
Here is how this tutorial translated for me:
const SlidingStack = createStackNavigator(
{
ScreenA,
ScreenC
}
);
const ModalStack = createStackNavigator(
{
SlidingStack,
ScreenB
},
{
mode: "modal"
}
);
The problem with this solution is, that the header now renders double when I'm on ScreenA
. Furthermore when I open the modal ScreenB
the back button is blank.
Edit
In my attempt to solve this problem following the documentation, I found a solution for the double header rendering:
const SlidingStack = createStackNavigator(
{
ScreenA,
ScreenC
}
);
const ModalStack = createStackNavigator(
{
SlidingStack,
ScreenB
},
{
mode: "modal",
navigationOptions: ({ navigation }) => {
const options = {}
if (navigation.state.routeName === "SlidingStack") options["header"] = null;
return options;
}
}
);
The problem with this solution is, that the back buttons still do not have any text.
Edit:
Following what I've learned from Pritish, here is the code I ended up with:
const IOS_MODAL_ROUTES = ["OptionsScreen"];
let dynamicModalTransition = (
transitionProps: NavigationTransitionProps,
prevTransitionProps: NavigationTransitionProps
): TransitionConfig => {
if (
IOS_MODAL_ROUTES.some(
screenName =>
screenName === transitionProps.scene.route.routeName ||
(prevTransitionProps && screenName === prevTransitionProps.scene.route.routeName)
)
) {
return StackViewTransitionConfigs.defaultTransitionConfig(
transitionProps,
prevTransitionProps,
true
);
}
return StackViewTransitionConfigs.defaultTransitionConfig(
transitionProps,
prevTransitionProps,
false
);
};
It uses React Navigation V2's owns transitions.