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,
},
});