Reputation: 847
I'm using React Navigation to create tab navigator in my app, what I want to do is hide that tab bar when user scrolls down and bring it back again when user scroll to top again, Is there any cross-platform solution to that?
reference app is Linkedin
Upvotes: 6
Views: 19720
Reputation: 319
If your tab bar is a part of a native stack, then you can not acess showTabBar, what you can do in this case is just to toggle the display of the tab bar, if not, just use showTabBar
Upvotes: 0
Reputation: 47
I have implemented a custom ScrollView component that can be wrap inside any child component to achieve hide and show bottom functionality in react-navigation version 6+
<ScrollView
onScroll={scroll}
scrollEventThrottle={16}
refreshControl={refreshControl ? refreshControl : undefined}
{...props}>
{children}
</ScrollView>
And the scroll function will be something like this.
const navigation = useNavigation()
const parent = navigation.getParent();
const onScroll = (event: any) => {
const currentOffset = event.nativeEvent.contentOffset.y;
const dif = currentOffset - currentPos;
if (currentOffset == 0) {
parent?.setOptions({ tabBarStyle: { display: 'flex', animated: true } });
}
if (Math.abs(dif) < 3) {
} else if (dif < 0) {
parent?.setOptions({ tabBarStyle: { display: 'flex', animated: true } });
} else {
parent?.setOptions({ tabBarStyle: { display: 'none', animated: true } });
}
currentPos = currentOffset;
};
Upvotes: 0
Reputation: 215
I have implemented component that show/hide Bottom Tab Bar. Based on the scroll direction param showTabBar
is set.
export default class ScrollTab extends React.Component {
onScroll = (event) => {
const { navigation } = this.props;
const currentOffset = event.nativeEvent.contentOffset.y;
const dif = currentOffset - (this.offset || 0);
if (dif < 0) {
navigation.setParams({ showTabBar: true });
} else {
navigation.setParams({ showTabBar: false });
}
//console.log('dif=',dif);
this.offset = currentOffset;
}
render () {
return (
<ScrollView onScroll={(e) => this.onScroll(e)}>
{this.props.children}
</ScrollView>
);
}
}
Then in navigationOptions
it is possible to change tabBarVisible
property depending on the showTabBar
param.
const isTabBarVisible = (navState) => {
if (!navState) {
return true;
}
let tabBarVisible = navState.routes[navState.index].params ? navState.routes[navState.index].params.showTabBar : true;
return tabBarVisible;
}
const MessagesStack = createStackNavigator(
{
Messages: MessagesScreen,
},
config
);
MessagesStack.navigationOptions = ({ navigation }) => {
return {
tabBarLabel: 'Messages',
tabBarVisible: isTabBarVisible(navigation.state)
}
};
Upvotes: 6
Reputation: 437
Edit: See this Github issue for the answer.
Old answer: Based on a scrolling event from the Scroll View, you can set the tabBarVisible navigation option to false. If you want to have an animated smooth you could look into adjusting the height of the tabBar or moving the tabBar offscreen. I haven't tested any of this, but it would be the first thing I'd look into.
Upvotes: 3