-
-
Notifications
You must be signed in to change notification settings - Fork 5.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Choose transition mode for each screen in StackNavigator #707
Comments
This is (probably ?) related to #690 |
This is a super common question and it isn't easy to fix properly, but here is a hack that you may enjoy. First, you'll need this: const MultiNavigator = (routeConfigs) => {
const modalNavigatorRoutes = {};
Object.keys(routeConfigs).forEach(routeName => {
const InnerNavigator = StackNavigator(routeConfigs);
modalNavigatorRoutes[routeName+'Modal'] = { screen: InnerNavigator };
});
return StackNavigator(modalNavigatorRoutes, {mode: 'modal'});
}; Now, you can use this new magical thing: const MyApp = MultiNavigator({
Home: {screen: HomeScreen},
Profile: {screen: ProfileScreen},
}); Now, inside your app you can use the normal routes, like I'm going to close this out, but if you have a suggestion on an alternative API, feel free to open a proposal as another issue. |
@ericvicenti I think there's a bug in your code above.. calling |
Same as @richardfickling |
I get the same bug @richardfickling , did you find a workaround ? |
In terms of API, how about adding (to be fair, I've not gone through the transitioner / stacknavigator code, so access to screen options may not be possible) |
I display the |
Is anyone else here getting a back button in their modals using the nesting configuration shown by @richardfickling? |
Oh yeah, headers are likely messed up. I have my own custom header throughout my app, so I've never had that issue |
Something like that @antgly import { HeaderBackButton } from 'react-navigation';
static navigationOptions = ({ navigation }) => ({
headerLeft: <HeaderBackButton onPress={() => navigation.dispatch({ type: 'Navigation/BACK' })} />,
headerTitle: "Title"
}) |
@tdurand I have the opposite issue. |
@richardfickling In the code below, if you set
|
I have my own custom header on every screen, so I use headerMode: none on all of my navigators |
@richardfickling how did you connect your custom header with navigator? Or you mean something like this:
|
yeah, it's basically what you said. In my screen's view, |
With 1.0-beta9, I set |
@richardfickling Could you pls give more details on the usage of
I got
|
The modal workaround above from @ericvicenti doesn't work. It opens up the home screen instead of the screen that you specify. Also, it ignores navigation options - although I'm sure you were just giving an example and you could the example code to apply them. |
@richardfickling Your workaround works wonderfully! Thank you! That should be the goto solution. The issue of not being able to navigate again through the card stack from there is not important to my use case because I'm just loading one off modals. |
Hello, |
The solution from @richardfickling works great but it's cumbersome to have to manually add
But then the back button will always have the text 'Back' instead of the previous screen name. |
Even if @richardfickling's solution fixed the problem, I now have a bigger one ! I have my screens configured like this :
When I navigate to CustomModal everything works. I have a nice route from Home to CustomModal. But when I navigation to DetailShow... I get my screen, but when I look at the route I get only one element : Home That's a real problem because it means you can't use .goBack() and it'd close your app if you use it on an Android device. Any idea? |
I really like @richardfickling's and @ericvicenti's approach, so this is what I did to get it working on my end (essentially combined both of their approaches). FULL DISCLOSURE: Not fully tested yet, haven't tried it out with headers. Will post another update as this evolves. const StackModalNavigator = (routeConfigs, navigatorConfig) => {
const CardStackNavigator = StackNavigator(routeConfigs, navigatorConfig);
const modalRouteConfig = {};
const routeNames = Object.keys(routeConfigs);
for (let i = 0; i < routeNames.length; i++) {
modalRouteConfig[`${routeNames[i]}Modal`] = routeConfigs[routeNames[i]];
}
const ModalStackNavigator = StackNavigator({
CardStackNavigator: { screen: CardStackNavigator },
...modalRouteConfig
}, {
mode: 'modal',
headerMode: 'none'
});
return ModalStackNavigator;
}; Create the navigator: const RootNavigator = StackModalNavigator({
Intro: {
screen: Intro
},
Profile: {
screen: Profile
},
Browse: {
screen: Browse
}
}, {
headerMode: 'none'
});
// ...
<RootNavigator /> Usage: // Navigate with regular transition
this.props.navigate('Profile')
// Navigate with modal transition (just append "Modal" to the end of the route name)
this.props.navigate('ProfileModal') |
I had the issue with the @richardgirges's implementation when I had nested const StackModalNavigator = (name, routeConfigs, navigatorConfig) => {
const CardStackNavigator = StackNavigator(routeConfigs, navigatorConfig);
const modalRouteConfig = {};
const routeNames = Object.keys(routeConfigs);
for (let i = 0; i < routeNames.length; i++) {
modalRouteConfig[`${routeNames[i]}Modal`] = routeConfigs[routeNames[i]];
}
const ModalStackNavigator = StackNavigator(
{
[name]: { screen: CardStackNavigator },
...modalRouteConfig
},
{
mode: 'modal',
headerMode: 'none'
}
);
return ModalStackNavigator;
}; |
Guys. here is what you want. And do like this when you want to go to modal and back.
|
@richardgirges @gontovnik thank you for this great implementation! It worked great for iOS, and now trying to port my app over to Android and finding that all routes are transitioning like a modal. Have you experienced this as well? |
@bradbumbalough i think that is not a problem, Android default screen transition just like a modal |
@bradbumbalough @xiaogliu You have to manually declare the transitionConfig for the StackNavigator you have intended for import { StackNavigator } from 'react-navigation'
import CardStackStyleInterpolator from 'react-navigation/src/views/CardStack/CardStackStyleInterpolator'
const CardStackNavigator = StackNavigator(
{
Home: { screen: Home },
Screen1 : { screen: Screen1 },
},
{
initialRouteName: 'Home',
headerMode: 'none',
transitionConfig() {
return { screenInterpolator: CardStackStyleInterpolator.forHorizontal }
},
},
) However, my problem with this nested stack navigator solution to have both modal and card mode is that for Android, it is horribly slow in transition to reset a route from a nested stack to the root stack. In my case I have a root stack with |
Does anyone have a nice recipe for a Modal in an App that uses const Main = TabRouter(
{
Screen1: {
screen: Screens.One,
},
Screen2: {
screen: Screens.Two,
},
},
{
initialRouteName: 'Screen1',
});
const MyApp = createNavigationContainer(createNavigator(Main)(AppScreen)); The approach with two nested "Navigators" does not work here as far as my tests went. I cannot add TabRouter as a child to the root Navigator. I'm currently stuck. Anyone? |
make the tabnavigator a child of a stacknavigator
|
I'm going to lock this issue because it's not a useful place to continue discussions. Feel free to comment further on here: react-navigation/rfcs#10 |
I migrated over from react-native-router-flux. There it was possible for each screen to define whether it should transition vertically or horizontally. I have not seen any easy and quick way to do this like with router-flux until now.
The text was updated successfully, but these errors were encountered: