Ammar Tariq
Ammar Tariq

Reputation: 847

How to create Bottom Tab Bar that disappears on scroll in React Native?

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

Answers (4)

Abdulrazzak Alsssouki
Abdulrazzak Alsssouki

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

Saad Sheikh
Saad Sheikh

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

Dzmitry
Dzmitry

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

martwetzels
martwetzels

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

Related Questions