skip to Main Content

How to remove the bottom and top navigation on scrolling? Many apps like youtube hide their bottom and top navigation when a user is scrolling it can post feeds etc How can I do this with my code? for example, if a user is scrolling it hides the bottom and top navigation with smooth animation, and then posts cover the screen and when I stop it comes back bottom and top navigation can anyone help me to do that?

I created a small app on Expo Snack if you want to consider helping me feel free to check that out link https://snack.expo.dev/@syblus/stackoverflowquastion the web version if not good but the expo go version is good

2

Answers


  1. You could try use something like this and use headerIsShown state to apply a class that animates it in/out with transform: [{ translateY: headerIsShown ? 0 : - 60 }],
    If you want to animate it, you could use react native interpolation
    https://reactnative.dev/docs/animations#interpolation

    <ScrollView
      onScroll={(event) => {
        const scrolling = event.nativeEvent.contentOffset.y;
        
        if (scrolling > 100) {
          setHeaderShown(true);
        } else {
          setHeaderShown(false);
        }
      }}
      style={{ flex: 1 }}
    >
      {images.map(( { uri } ) => (
        <Image source={{ uri: item.download_url }} style={styles.image} />
      ))}
    </ScrollView>
    
    Login or Signup to reply.
  2. The top answer to this question: how to Show or hide Navbar when scroll use react.js? is a nice example of how this can be done. The below is a modified version of this where the scroll logic is placed into a custom hook. You then need to set the positioning of your top and bottom navs as position: fixed and change the location of them (top/bottom) depending on the show state.

    // useShowHideElement.js
    import { useEffect, useState } from 'react';
    
    const useShowHideElement = () => {
      const [showElement, setShowElement] = useState(true);
      const [prevScrollPos, setPrevScrollPos] = useState(0);
    
      const controlElement = () => {
        if (typeof window !== 'undefined') {
          if (window.scrollY > prevScrollPos) {
            setShowElement(false);
          } else {
            setShowElement(true);
          }
    
          setPrevScrollPos(window.scrollY);
        }
      };
    
      useEffect(() => {
        if (typeof window !== 'undefined') {
          window.addEventListener('scroll', controlElement);
    
          return () => {
            window.removeEventListener('scroll', controlElement);
          };
        }
      }, [prevScrollPos]);
    
      return {
        show: showElement,
      };
    };
    
    export default useShowHideElement;
    
    
    // bottomNav.js
    import React from 'react';
    import { StyleSheet, View } from 'react-native';
    import FontAwesome from 'react-native-vector-icons/FontAwesome';
    import Ionicons from 'react-native-vector-icons/Ionicons';
    import useShowHideElement from './useShowHideElement';
    
    const BottomNav = () => {
      const { show } = useShowHideElement();
      let page = 'home';
    
      return (
        <View style={{ ...styles.container, bottom: show ? 0 : '-100px' }}>
          {page === 'home' ? (
            <FontAwesome name='home' size={24} color='black' style={styles.activeIcon} />
          ) : (
            <FontAwesome name='home' size={24} color='black' style={styles.icons1} />
          )}
          {page === 'profile' ? (
            <FontAwesome name='user-circle' size={24} color='black' style={styles.activeIcon} />
          ) : (
            <FontAwesome name='user-circle' size={24} color='black' style={styles.icons1} />
          )}
        </View>
      );
    };
    
    export default BottomNav;
    
    const styles = StyleSheet.create({
      container: {
        display: 'flex',
        flexDirection: 'row',
        justifyContent: 'space-evenly',
        backgroundColor: 'gray',
        borderTopLeftRadius: 20,
        borderTopRightRadius: 20,
        position: 'fixed',
        transition: '225ms',
        width: '100%',
        zIndex: 100,
        paddingVertical: 10,
        alignItems: 'center',
      },
      activeIcon: {
        backgroundColor: 'white',
        borderRadius: 50,
        fontSize: 30,
        padding: 10,
      },
      icons1: {
        color: 'white',
        fontSize: 30,
        marginRight: 20,
        marginLeft: 20,
      },
    });
    
    //topNav.js
    import React, { useEffect, useState } from 'react';
    import { StyleSheet, View, StatusBar, FlatList, Image } from 'react-native';
    import Ionicons from 'react-native-vector-icons/Ionicons';
    import Entypo from 'react-native-vector-icons/Entypo';
    import useShowHideElement from './useShowHideElement';
    
    const TopNav = () => {
      const { show } = useShowHideElement();
      let page = 'home';
    
      return (
        <View
          style={{
            flexDirection: 'row',
            alignItems: 'center',
            justifyContent: 'space-between',
            width: '100%',
            paddingVertical: 12,
            position: 'fixed',
            top: show ? 0 : '-100px',
            zIndex: 100,
            backgroundColor: 'gray',
            transition: '225ms',
          }}
        >
          <Entypo name='app-store' size={24} color='white' style={styles.icons1} />
          {page === 'home' && <Ionicons name='trophy' size={24} color='white' style={styles.icons11} />}
          {page === 'profile' && <Ionicons name='settings-sharp' size={24} color='black' style={styles.icons11} />}
        </View>
      );
    };
    
    export default TopNav;
    
    const styles = StyleSheet.create({
      icons11: {
        color: 'white',
        fontSize: 30,
        marginRight: '3%',
      },
      icons1: {
        color: 'white',
        fontSize: 30,
        marginRight: 20,
        marginLeft: 20,
      },
    });
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search