Liam Kelly
Liam Kelly

Reputation: 141

Get height of tab bar on any device in React-Navigation

I'd like to position a component just above the createBottomTabNavigator TabBar in React-Navigation V2.

The height of the tab bar seems to differ on various devices (iOS devices especially). Is there a way to calculate the height of the tab bar as it is displayed on a device?

Upvotes: 14

Views: 29167

Answers (5)

Tom Bombadil
Tom Bombadil

Reputation: 3975

React Navigation 5 +

You now have two options to get the height of the bottomTabBar.

To get the height of the bottom tab bar, you can use BottomTabBarHeightContext with React's Context API or useBottomTabBarHeight, which is a custom Hook:

import { BottomTabBarHeightContext } from '@react-navigation/bottom-tabs';

// ...

<BottomTabBarHeightContext.Consumer>
  {tabBarHeight => (
    /* render something */
  )}
</BottomTabBarHeightContext.Consumer>

or

import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';

// ...

const tabBarHeight = useBottomTabBarHeight(); 

Make sure you use version 5.11.9 or greater

Upvotes: 25

ICW
ICW

Reputation: 5760

The other answer by benny points to where you need to go, but doesn't give you an easy way to check if . To complete the answer, I'll elaborate on the exact checks required to know which height to use. First we need to know if the tab bar is in adaptive mode or not. If you haven't passed "adaptive" as a parameter, adaptive is set to true for all iOS devices with iOS 11+. If it's not iOS11+, then adaptive is false. So, if you HAVE NOT passed "adaptive" as a parameter to tabBarOptions, the function is:

import {Platform, Dimensions} from 'react-native';
const isLandscape = () => {
    const dim = Dimensions.get('screen');
    return dim.width >= dim.height;
};
function tabBarHeight() {
    const majorVersion = parseInt(Platform.Version, 10);
    const isIos = Platform.OS === 'ios';
    const isIOS11 = majorVersion >= 11 && isIos;
    if(Platform.isPad) return 49;
    if(isIOS11 && !isLandscape()) return 49;
    return 29;
}

Upvotes: 0

Vladislav Zaynchkovsky
Vladislav Zaynchkovsky

Reputation: 3319

To avoid Ipnone X issues they use react-native-safe-area-view inside.

You just need to know padding at bottom:

import { getInset } from 'react-native-safe-area-view'
const bottomOffset = getInset('bottom')

It solved problem for us.

We also use specific component position.

Updated according to library update:

import { SafeAreaConsumer } from 'react-native-safe-area-context'

<SafeAreaConsumer>
   {insets => (
      <TouchableOpacity
          style={{
               paddingBottom: 11 + insets.bottom,
          }}
        >
          ...
      </TouchableOpacity>
   )}
</SafeAreaConsumer>

or hook:

const insets = useSafeArea();

Upvotes: 4

Burak
Burak

Reputation: 710

For your issue of how to position something above the tab bar, you can also achieve this without absolute positioning. This way you aren't relying on how the logic of determining the height of the bar is implemented (which may also change in the future).

import { createBottomTabNavigator, BottomTabBar } from "react-navigation"

createBottomTabNavigator({
    // Your tabs
}, {
    tabBarComponent: (props) => <BottomTabBar {...props} />
})

For example, if you wanted a little red bar above your tabs, you could do the following

tabBarComponent: (props) => (
    <View>
        <View style={{ backgroundColor: "red", height: 10 }} />
        <BottomTabBar {...props} />
    </View>
)

Upvotes: 3

bennygenel
bennygenel

Reputation: 24660

As you check the source code for react-navigation-tabs which react-navigation uses for createBottomTabNavigator, you can see that there is only 2 different bottom tab bar heights. Compact and default, which changes between some conditions. You can also set your component's position according to these conditions manually.

Upvotes: 8

Related Questions