How to hide bottom tab navigator when scroll up the screen? - react-native

Is there a way to hide the bottom tab navigator when you scroll up the screen?
I have attempted to use route params to set tabBarVisible to false but I think it is not working because I have nested navigator. In other words, my tab in my tab navigator is another stack navigator.
In my bottom tab navigator I tried doing this...
Tab1: {
screen: OtherStack,
navigationOptions: ({navigation}) => {
const routeParams = navigation.state.params
return {
tabBarVisible: routeParams && routeParams.tabBarVisible,
tabBarIcon: ...
}
}
},
},
Then in my OtherStack I use createNavigator to create a screen like this...
NewScreen: {
screen: NewScreen,
navigationOptions: ({ navigation }) => {
return {
headerTitle: <Header />,
headerStyle: {backgroundColor: '#f6f6f6'},
headerLeft: null,
}
}
Then as a test, in the NewScreen I am calling a function via touchableOpacity onPress...
onPress={() => navigation.setParams({ tabBarVisible: false })}
But nothing happens. I want to get this to hide the tab bar when I click the button, and after I get that to work I want to call that function onScroll.
Does anyone know how to do this?

Related

react navigation 5 hide bottom tab nav in nested navigation

The structure of my react navigation is like this : BottomTabNavigator => Navigator => Components
This is the skeleton of the App.js. The whole application is wrapped up in a bottom tab navigation.
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
const BottomTab = createBottomTabNavigator();
function App() {
return (
<NavigationContainer>
<BottomTab.Navigator >
<BottomTab.Screen
name="Main"
component={MyVeranda}
options={{
tabBarLabel: 'Home',
tabBarIcon: //...some icon,
}}
/>
//...some other screens
</BottomTab.Navigator>
</NavigationContainer>
);
}
export default App;
As you can see, inside the bottom tab i have screen name "Main" that uses MyVeranda component. MyVeranda itself is a stack navigator, which have 2 screens components : MyHome and BuyForm
import { createStackNavigator } from '#react-navigation/stack';
const HomeStack = createStackNavigator();
function MyVeranda({ route,navigation }) {
//..some states, props, etc
return (
<HomeStack.Navigator>
<HomeStack.Screen
name="MyHome"
component={MyHome}
options={{/*...some options*/ }}
/>
<HomeStack.Screen
name="BuyItem"
component={BuyForm}
options={{/*...some options*/}}
/>
</HomeStack.Navigator>
);
}
export defaul MyVeranda;
MyVeranda is a parent of MyHome and BuyForm, both are just 2 simple functional components
function MyHome({navigation}){
//..some states, props, etc
return (
<ScrollView contentContainerStyle={{/*...some styling*/}}>
//...some components
</ScrollView>
);
}
function BuyForm({navigation}){
//..some states, props, etc
return (
<ScrollView contentContainerStyle={{/*...some styling*/}}>
//...some components
</ScrollView>
);
}
My question is : how to hide the root bottom tab navigator when navigating to BuyForm component, but not when go to MyHome component?
Based from answer of this question, i know that i can hide the bottom tab if i put this line navigation.setOptions({ tabBarVisible: false }) in MyVeranda component
function MyVeranda({ route,navigation }) {
//..some states, props, etc
navigation.setOptions({ tabBarVisible: false })//this hide the bottom tab navigator
return (
//...
)
}
But this hide the bottom tab entirely when i am at both MyHome and BuyForm component.
Calling navigation.setOptions({ tabBarVisible: false }) in BuyForm seems to do nothing
function BuyForm({ route,navigation }) {
//..some states, props, etc
navigation.setOptions({ tabBarVisible: false }) //this do nothing
return (
//...
)
}
So my guess is i have to call navigation.setOptions({ tabBarVisible: false }) inside MyVeranda when BuyForm is the active screen, but i cannot the proper syntax to get the current active screen from a stack navigator component?
Here is the answer
React Navigation how to hide tabbar from inside stack navigation
Indeed you can use setOptions on the navigation to set custom options. Although it's recommended to rather reorganize the navigation structure. This might be possible if you create a StackNavigator not nested with the TabBar.
React.useLayoutEffect(() => {
navigation.setOptions({ tabBarVisible: false });
}, [navigation]);

React Native Navigation To External Tab Within BottomTabBar Screen

I have an issue where I do not know how to navigate from a screen in a bottom tab bar that looks like this:
default: createBottomTabNavigator(
{
Home: {
screen: HomeScreen,
navigationOptions: {
tabBarIcon: ({ tintColor }) => <Ionicons name="ios-home" size={24} color={tintColor} />
}
},
Message: {
screen: MessageScreen,
navigationOptions: {
tabBarIcon: ({ tintColor }) => <Ionicons name="ios-chatboxes" size={24} color={tintColor} />,
OtherUser: { screen: OtherUserScreen }
}
},
Post: {
screen: PostScreen,
navigationOptions: {
tabBarIcon: ({ tintColor }) => <Ionicons name="ios-add-circle" size={48} color={"#4cdd75"} style={{
shadowColor: "#4cdd75",
shadowOffset: {
width: 0,
height: 0
},
shadowRadius: 10,
shadowOpacity: 0.3
}} />
}
},
Notification: {
screen: NotificationScreen,
navigationOptions: {
tabBarIcon: ({ tintColor }) => <Ionicons name="ios-notifications" size={24} color={tintColor} />
}
},
Profile: {
screen: ProfileScreen,
navigationOptions: {
tabBarIcon: ({ tintColor }) => <Ionicons name="ios-person" size={24} color={tintColor} />
}
}
}
With the createSwitchNavigator component looking like this:
export default createAppContainer(
createSwitchNavigator(
{
Loading: LoadingScreen,
App: AppContainer,
Auth: AuthStack,
OtherUser: OtherUserScreen
},
{
initialRouteName: 'Loading'
}
)
);
The AppContainer is the bottom tab navigator screen setup.
Additionally, My navigation from within my message screen looks like this:
const { navigate } = this.props.navigation;
...
onPress={() => navigate('OtherUser')}
From this message screen I want to navigate to the OtherUser screen so that the bottom tab navigator is still shown. Currently, the navigation navigates to the OtherUser screen, but the bottom tab navigator dissapears. And when I try to use the back button code navigation in my OtherUser Screen that looks like this:
onPress={() => navigate("MessageScreen")}
Nothing is shown. Would it be possible in any way to have the navigation from message screen to the other user screen seemless without deleting the bottom tab bar and without adding another component to it?
From what I see, what you're trying to do is wrong.
It makes sense that the bottomBar disappears because you use a SwitchNavigator to navigate between "AppContainer" and "OtherUser".
So the moment you navigate to "OtherUser", you are no longer in a bottomMenu navigation, you are simply in a SwitchNavigator!
To be able to do what you want to do, you should integrate a stackNavigator instead of MessageScreen,
then in this StackNavigator, you integrate your MessageScreen as well as OtherUser
Currently, your navigation seems to be like this:
- Loading
- App
-- bottomTabMenu
-- Home
-- Message
-- Posts
-- Notifications
-- Profile
- Auth
- OtherUser
So as you see, when you go to "OtherUser" you are not in a BottomMenu navigation anymore, besides that, you can't go back because actually, to be able to go back with a back button, you need to be in a stack navigation.
So if you want to be able to go to the user profile from your messageScreen, you need to wrap it in a navigation stack, and integrate this stack into your bottomMenu.
Your navigation should then look something like this:
- Loading
- App
-- bottomTabMenu
-- Home
-- Message
-- Stack Navigation
-- Message Screen (defaultRoute)
-- OtherUser Screen
-- Posts
-- Notifications
-- Profile
- Auth
So your code will be something like this:
const MessageStack = createStackNavigator(
{
Message: MessageScreen,
OtherUser: OtherUserScreen
},
{
initialRouteName: "Message"
}
)
default: createBottomTabNavigator(
{
...
Message: {
screen: MessageStack,
navigationOptions: {
tabBarIcon: ({ tintColor }) => <Ionicons name="ios-chatboxes" size={24} color={tintColor} />,
OtherUser: { screen: OtherUserScreen } //Delete this line, the navigationOptions are only used to define styles or behaviors on the navigation.
}
},
...
}
I hope I understood the question and that this answer will help you!
Viktor

how to add header Left to createMaterialTopTabNavigator?

I have createMaterialTopTabNavigator and createDrawerNavigator navigation system I want to add a menu bar icon to the screens of createMaterialTopTabNavigator , so I went to the screen/component and added this code , but nothing has been added and there is no errors at the console , could you please check my code if its correct
static.navigationOptions = {
headerLeft: () => {
return ( <Icon
name = 'menu'
size = { focused ? 28 : 20}
color = {tintColor}
style={{paddingTop:20}}
/>)}}
if you're trying to put the menu icon on top of the tabBar, you will have to use StackNavigator.
const TabPage = createMaterialTopNavigator({
...
})
const YNavigator = createStackNavigator ({
Home:{screen: TabPage,
navigationOptions: ({navigation}) => ({
headerLeft: <Icon name="home" size={15} color="blue" />,
})
},
})
hope this helps

Ripple effect on TabBarBottom

How to add ripple animation when a tabs is clicked in TabBarBottom. I want ripple effect just like Youtube app
You can use Screen's Navigation Options to add desired styled tabBarIcon
tabBarIcon
React Element or a function that given { focused: boolean, tintColor:
string } returns a React.Element, to display in tab bar
tabBarLabel
Title string of a tab displayed in the tab bar or React Element or a
function that given { focused: boolean, tintColor: string } returns
a React.Element, to display in tab bar. When undefined, scene title
is used. To hide, see tabBarOptions.showLabel in the previous
section.
tabBarOnPress
Callback to handle tap events; arguments are the scene: { route,
index } that was tapped and a jumpToIndex method that can perform
the navigation for you.
Example
const MyApp = TabNavigator({
Home: {
screen: MyHomeScreen,
navigationOptions: ({navigation}) => ({
tabBarIcon: ({focuced, tintColor}) => (
<MyCustomIcon focuced={focuced} tintColor={tintColor} name="Home" />
)
})
},
Notifications: {
screen: MyNotificationsScreen,
navigationOptions: ({navigation}) => ({
tabBarIcon: ({focuced, tintColor}) => (
<MyCustomIcon focuced={focuced} tintColor={tintColor} name="Notifications" />
)
})
},
});

Add hamburger button to React Native Navigation

I'm very new to React-Native so I definitely may be missing something. But all I want to do is add a hamburger type button to a settings page in the main Navigation bar. I have set up a link in the main part of that works the way I want hamburger button to work.
Screenshot
import React from 'react';
import { AppRegistry, Text, View, Button } from 'react-native';
import { StackNavigator } from 'react-navigation';
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',
headerLeft: <Button onPress={ WHAT GOES HERE?? } title= "=" />
};
render() {
const { navigate } = this.props.navigation;
return (
<Button
onPress={() => navigate('Settings')}
title="Link to Settings" />
);
}
}
class Settings extends React.Component {
static navigationOptions = {
title: 'Settings',
headerLeft: <Button title= "=" />
};
render() {
return <Text>Hello, Settings!</Text>;
}
}
const SimpleApp = StackNavigator({
Home: { screen: HomeScreen },
Settings: { screen: Settings}
});
AppRegistry.registerComponent('NavPractice', () => SimpleApp);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
Having this, you're very close to the solution.
static navigationOptions = {
title: 'Welcome',
headerLeft: <Button onPress={ WHAT GOES HERE?? } title= "=" />
};
A little-known fact is that navigationOptions accepts a function that returns navigation options. That function accepts some props, navigation one of them. Know this, adjust your code a little.
static navigationOptions = function(props) {
return {
title: 'Welcome',
headerLeft: <Button onPress={() => props.navigation.navigate('DrawerOpen')} title= "=" />
}
};
check this link with same issue https://github.com/react-community/react-navigation/issues/1539
check navigationOptions
navigationOptions: ({ navigation }) => ({
title: 'Schedules', // Title to appear in status bar
headerLeft: <Icon name="menu" size={35}
onPress={ () => navigation.navigate('DrawerOpen') } />
from
const SchedulesStack = StackNavigator({
Schedules: {
screen: SchedulesScreen,
navigationOptions: ({ navigation }) => ({
title: 'Schedules', // Title to appear in status bar
headerLeft: <Icon name="menu" size={35} onPress={ () => navigation.navigate('DrawerOpen') } />
})
}
});
const Homestack = StackNavigator({
Home: {
Screen: Home
navigationOptions: ({ navigation }) => ({
title: 'Home', // Title to appear in status bar
headerLeft: <Icon name="menu" size={35} onPress={ () => navigation.navigate('DrawerOpen') } />
})
}
});
const Root = DrawerNavigator({
Home: {
screen: HomeStack,
navigationOptions: {
title: 'Home' // Text shown in left menu
}
},
Schedules: {
screen: SchedulesStack,
navigationOptions: {
title: 'Schedules', // Text shown in left menu
}
}
}
})
In the above code it seems you are adding options to the sidebar and navigating to the sidebar menus.
//sidebar menu no.1
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',
headerLeft: <Button onPress={//action taken when option in the menu bar is clicked} title= "//the title of the screen where you will navigate and the sidebar menu lable" />
};
render() {
const { navigate } = this.props.navigation;
return (
<Button
onPress={() => navigate('Settings')}
title="Link to Settings" />
);
}
}
In this way you can create as many drawer options as you can.. now how to combine drawer options:
//react navigation provides you with DrawerNavigator API
const MyApp = DrawerNavigator({
Home: {
screenA: HomeScreen ,
},
Settings: {
screen: MySettingScreens,
},
});
The drawer also comes with a prop that is screenProps={/* this prop will get passed to the screen components and nav options as props.screenProps */}, like this :
<MyApp
screenProps={/* this prop will get passed to the screen components and nav options as props.screenProps */}
/>
Following are the props that react navigator provide to open/close drawer.
this.props.navigation.navigate('DrawerOpen'); // open drawer
this.props.navigation.navigate('DrawerClose'); // close drawer
You can also set the drawer style according to you, like this:
drawerWidth - Width of the drawer
drawerPosition - Options are left or right. Default is left position.
contentComponent - By default there is no scrollview available in the drawer. In order to add scrollview in the drawer you need to add contentComponent in the configuration.
contentOptions - As the name suggest these are used to give color to the active and inactive drawer items (label).
Cheers :)