So this is the case. I have let's say login screen which is tab based, one tab is login and other one is register. I also have "Forgot password" button. So when I press forgot password button I want to go to a single screen which does not contain tab navigation and has that "back" button in it's header.
This is my Navigator if this is helps in any way:
const LoginStack = createStackNavigator({
Login: LoginScreen,
});
LoginStack.navigationOptions = {
tabBarLabel: 'Login',
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={"login"}
/>
),
tabBarOptions: {
activeTintColor: "black",
}
};
const RegisterStack = createStackNavigator({
Register: RegisterScreen,
});
RegisterStack.navigationOptions = {
tabBarLabel: 'Register',
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={"account-plus"}
/>
),
tabBarOptions: {
activeTintColor: "black",
}
};
export default createBottomTabNavigator({
LoginStack,
RegisterStack,
});
If you need any more info, please comment.
Thanks!
Instead of directly exporting createBottomTabNavigator, you create tabs then follow as below
const Tabs = createBottomTabNavigator({
LoginStack,
RegisterStack,
});
const AppNavigator = createStackNavigator({
Tabs,
ForgotPassword: {
screen: ForgotPassword,
}
}) //fixed brackets
export AppNavigator
Related
Im making an app in React Native, and am looking to have a page that displays the bottom navigation bar but isn't directly on that navigation bar, i.e. it is sort of a child of another page though does not need to be access through the bottom Nav.
However, whenever I take it out of the bottom tab navigator it won't hide the icon, and if it is not added it wont allow me to see the bottom nav when I go to that page.
The code is as follows;
{
History: {
screen: HistoryScreen,
navigationOptions: {
tabBarIcon: ({ focused, tintColor }) =>
<Icon
focused={focused}
color={{ tintColor }}
name="history"
size={20}
zIdex="13"
solid
/>
}
},
Home: {
screen: HomeScreen,
navigationOptions: {
tabBarIcon: ({ focused, tintColor }) =>
<Icon
focused={focused}
color={ Colors.gyroscopicOrgane }
name="home"
size={20}
zIdex="13"
solid
/>
}
},
ConcreteTest: {
screen: ConcreteTestScreen,
navigationOptions: {
tabBarIcon: ({ focused,tintColor }) => <
Icon name="cog"
focused={focused}
color={{ tintColor }}
size={20}
zIdex="13"
solid
/>
}
},
Settings: {
screen: SettingsScreen,
navigationOptions: {
tabBarIcon: ({ }) => {
showIcon: false
}
}
}
},
{
tabBarOptions: {
activeTintColor: "#E66F25",
inactiveTintColor: "#B8BBC4",
showLabel: false
}
}
)
const AppStack = createStackNavigator({
Home: HomeScreen,
History: HistoryScreen,
ConcreteTest: ConcreteTestScreen,
Settings: SettingsScreen,
});
const AuthStack = createStackNavigator({
Launch: LaunchScreen,
Login: LoginScreen,
SignUp: SignUpScreen
});
export default createAppContainer(
createSwitchNavigator(
{
Loading: LoadingScreen,
Launch: LaunchScreen,
Settings: SettingsScreen,
App: AppTabNavigator,
Features: AppStack,
Auth: AuthStack
},
{
initialRouteName: "Loading"
}
)
)
It might be helpful to attach a screenshot of your layout. Try positioning your element absolutely (position: absolute) and then using top: left: bottom: right: to align it. If you need it to display conditionally, try setting a variable elementVar = null; and then if (needs to be displayed) {elementVar = YOUR_ELEMENT_CONTENT} then simply use {elementVar} in your render(return()) function.
I defined a routes.js file where all the routes from my Drawer navigation are created. This works fine except in one instance. I have one StackNavigator like so:
const ChatScreens = createStackNavigator(
{
Chat: {
screen: Chat,
},
Transactions: {
screen: Transactions,
navigationOptions: {
headerLeft: (
<MaterialIcons
name="chat"
size={24}
style={{ color: colors.BLACK, marginLeft: 10 }}
onPress={() => navigation.popToTop()} //not working
/>
),
}
},
Logout: {
screen: AuthLoadingScreen,
},
},
{
mode: 'card',
initialRouteName: 'Chat',
navigationOptions: {
drawerIcon: getDrawerItemIcon('chat'),
}
},
);
This code, if removed would render a default "< Back" arrow that works just fine. However, I want to use the icon. I tried adding said navigationOptions inside my Transactions.js file but they just get ignored. The only way they take effect is by adding this inside my routes.js the problem, is that there is no navigation within the said file so, of course, I get the Can't find variable: navigation error.
I attempted to change this line to NavigationActions but it won't work either if I do .navigate() or .back(). The truth is that I know the best place for this navigationOptions is within my Transactions file but I can't figure out why it's not working over there.
So either could you a) help me understand why it won't work under Transactions.js or b) help me make the navigation work inside my routes.js for this case?
Just FYI, towards the bottom of my routes.js I have my DrawerNavigation created successfully the following way:
export default Drawer = createAppContainer(
createDrawerNavigator({
Chat:{
screen: ChatScreens,
},
Info:{
screen: InfoScreens,
},
User: {
screen: UserScreens,
},
Feedback: {
screen: FeedbackScreens,
navigationOptions: {
drawerLabel: <Hidden />
}
}
},
{
initialRouteName: 'Chat',
contentComponent: DrawerContent,
contentOptions: {
activeTintColor: colors.TURQUOISE,
itemsContainerStyle: {
marginVertical: 0,
},
iconContainerStyle: {
opacity: 1
}
}
})
);
If you want to use navigation in navigationOptions, you need to use the method like navigationOptions = ({ navigation, navigationOptions }) => {}
For example,
class A extends Component {
static navigationOptions = ({ navigation }) => {
return {
headerLeft: (
<MaterialIcons
name="chat"
size={24}
style={{ color: colors.BLACK, marginLeft: 10 }}
onPress={() => navigation.popToTop()}
/>
),
}
};
};
...
But you try to use navigation not defined.
onPress={() => navigation.popToTop()} // navigation is not defined
I have simple createBottomTabNavigator and one of it's tabs is createStackNavigator and inside this stack I have one screen which I want it to over lap the tab bar. I tried use tabBarVisible: false on this screen but no luck there.
Code:
const BookingsStack = createStackNavigator({
Commutes: {
screen: Commutes,
navigationOptions: {
title: "Commutes",
header: null,
}
},
Tickets: {
screen: Tickets,
navigationOptions: {
title: "Tickets",
header: null,
tabBarVisible: false
}
}
});
export const MainNav = createBottomTabNavigator({
Current: {
screen: Current,
navigationOptions: {
title: "Current",
tabBarIcon: ({ tintColor }) => (
<IconIO name="ios-bus" size={scale(20)} color={tintColor} />
)
}
},
BookingsStack: {
screen: BookingsStack,
navigationOptions: {
title: "Commutes",
tabBarIcon: ({ tintColor }) => (
<IconSL name="layers" size={scale(20)} color={tintColor} />
)
}
}
}
As given in the navigation document:
If we want to hide the tab bar when we navigate from the feed home to a details screen without shuffling navigators, we cannot set the tabBarVisible: false configuration in navigationOptions on DetailsScreen, because those options will only apply to the FeedStack. Instead, we can do the following:
const FeedStack = createStackNavigator({ FeedHome: FeedScreen,
Details: DetailsScreen, });
FeedStack.navigationOptions = ({ navigation }) => { let
tabBarVisible = true; if (navigation.state.index > 0) {
tabBarVisible = false; }
return {
tabBarVisible,
}; };
I found a solution in the react-navigation docs - the implementation look like this:
const ChildMainNav = createBottomTabNavigator({
Current: {
screen: Current,
navigationOptions: {
title: "Current",
tabBarIcon: ({ tintColor }) => (
<IconIO name="ios-bus" size={scale(20)} color={tintColor} />
)
}
},
Commutes: {
screen: Commutes,
navigationOptions: {
title: "Commutes",
tabBarIcon: ({ tintColor }) => (
<IconSL name="layers" size={scale(20)} color={tintColor} />
)
}
}
}
export const MainNav = createStackNavigator({
ChildMainNav: {
screen: ChildMainNav,
navigationOptions: {
header: null
}
},
// overlap screens
Tickets: {
screen: Tickets,
navigationOptions: {
title: "Tickets",
header: null,
tabBarVisible: false
}
}
});
The idea is to add the Tab navigator into Stack navigator and add in this stack any other screens you want to have different navigationOptions to overlap the ones in your Tab.
Link to docs under:
A tab navigator contains a stack and you want to hide the tab bar on specific screens
When I am on settings screen, I see that the Review Icon (favorite) is missing. It shows when I am back on Review screen. Why is that happening. See the screenshot I took. Pasting relevant code snippet from my project for reference.
const MainNavigator = TabNavigator({
map: { screen: MapScreen },
deck: { screen: DeckScreen },
review: {
screen: StackNavigator({
review: { screen: ReviewScreen },
settings: { screen: SettingsScreen }
})
}
}, {
tabBarPosition: 'bottom',
tabBarOptions: {
labelStyle: { fontSize: 12 }
}
});
class ReviewScreen extends Component {
static navigationOptions = props => {
const {navigation} = props;
const {navigate} = navigation;
return {
tabBarIcon: ({ tintColor }) => {
return <Icon name="favorite" size={30} color={tintColor} />
},
headerTitle: 'Review Jobs',
headerRight: (
<Button
title="Settings"
onPress={() => navigate('settings')}
backgroundColor="rgba(0,0,0,0)"
color="rgba(0, 122, 255, 1)"
/>
)
}
}
Leads here is appreciated.
There is an issue with your code, since you're setting every icon's tintColor in the static navigationOptions as
tabBarIcon: ({tintColor}) => {
return <Icon name="favorite" size={30} color={tintColor}/>
}
and there is none for the Settings Screen, which also expects an Icon as it is inside the TabNavigator, therefore null is being rendered there.
Therefore you need to set the navigationOptions in the Settings Screen as
static navigationOptions = props => {
const {navigation} = props;
const {navigate} = navigation;
return {
tabBarIcon: ({tintColor}) => {
return <Icon name="favorite" size={30} color={tintColor}/>
}
}
}
or you may add the default icons in your App.js navigation file as
screen: TabNavigator({
map: { screen: MapScreen,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="favorite" size={30} color={tintColor}/>
)
}
},
// ....so on
Hope it helps!
I am using ReactNavigation and after SignIn , i enter my home page. My home page has 4 tabs, and on 4th tab i have logout button. After clicking on logout button , i should get back to SIGN IN screen.
The issue i am facing is , i am not been able to reset the TAB NAVIGATOR.
this.props.navigation.dispatch({
type: NavigationActions.NAVIGATE,
routeName: 'SignIn',
action: {
type: NavigationActions.RESET,
index: 0,
actions: [{type: NavigationActions.NAVIGATE, routeName: 'SignIn'}]
}
})
I tried applying above chunk of code to navigate , but it did not work. Please tell me , how to get out of tab navigator.
Your root-level navigation should be a StackNavigator with children looking something like this:
Welcome screen
Login screen
Tab Navigator (for logged in home screen)
Tab 1
Tab 2
Tab 3
Tab 4 (with logout button)
To reset the TabNavigator, you shouldn't dispatch an action of type NavigationActions.NAVIGATE because that will push onto the current navigation stack, instead of removing the tab navigator from the state. Instead, consider using a Reset action. So the code within your logout function should have:
const resetAction = NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({ routeName: 'Login'})
]
})
this.props.navigation.dispatch(resetAction);
onPress of Logout we are calling below code
const resetAction = NavigationActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: "SignIn" })],
key: null
});
this.props.navigation.dispatch(resetAction);
This is our AppNavigation file is there any way to reset app on Logout
const PrimaryNav = StackNavigator(
{
SignIn: {
screen: SignIn,
navigationOptions: {
headerMode: "none",
header: null
}
},
SignUp: {
screen: SignUp,
navigationOptions: {
headerMode: "none",
header: null
}
},
TabsScreen: {
screen: TabsScreen,
navigationOptions: {
headerMode: "float",
headerTitleStyle: { color: "#ffffff" },
gesturesEnabled: true,
header: null,
}
},
)
export const sideMenuStack = StackNavigator({
SideMenu: {
screen: SideMenu,
navigationOptions: {
headerMode: "none",
header: null
}
},
Settings: {
screen: Settings,
navigationOptions: ({ navigation }) => ({
title: "Settings",
})
},
SignIn: {
screen: SignIn,
navigationOptions: {
headerMode: "none",
header: null
}
},
)
export const FeedsStack = StackNavigator({
FeedsStack: {
screen: FeedsStack,
navigationOptions: {
headerMode: "none",
header: null
}
},
Post: {
screen: Post,
navigationOptions: ({ navigation }) => ({
title: "Post",
})
},
)
export const UserStack = StackNavigator({
UserStack: {
screen: UserStack,
navigationOptions: {
headerMode: "none",
header: null
}
},
Friends: {
screen: Friends,
navigationOptions: ({ navigation }) => ({
title: "Friends",
})
},
)
export const TabView = TabNavigator(
{
FeedsStack: {
screen: FeedsStack,
navigationOptions: {
tabBarLabel: "Feeds",
scrollEnabled: true,
focussed: true,
tabBarIcon: ({ tintColor }) =>
<Image
source={Images.feedsActive}
style={[styles.icon, { tintColor: tintColor }]}
/>
}
},
UserStack: {
screen: UserStack,
navigationOptions: {
tabBarLabel: "Users",
tabBarIcon: ({ tintColor }) =>
<Image
source={Images.UserActive}
style={[styles.icon, { tintColor: tintColor }]}
/>
}
},
sideMenuStack: {
screen: sideMenuStack,
navigationOptions: {
tabBarLabel: "More",
headerMode: "screen",
tabBarIcon: ({ tintColor }) =>
<Image
source={Images.moreActive}
style={[styles.icon, { tintColor: tintColor }]}
/>
}
}
},
//Default configurations for Tabs
{
tabBarPosition: "bottom",
animationEnabled: true,
tabBarOptions: {
indicatorStyle:{
borderBottomColor:'#32a1fe',
borderBottomWidth:3
},
showLabel: true,
backBehavior: "none",
showIcon: true,
activeTintColor:"#338AD8",
inactiveTintColor:"#BEC5CB",
upperCaseLabel:false,
labelStyle :[styles.labelStyle],
}
}
);