-
-
Notifications
You must be signed in to change notification settings - Fork 5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to get the height of bottom navigator? #7359
Comments
there are several factors that impact the height: 1) is it compact or full height tab bar? this depends on whether landscape/portrait and whether you're using a tablet or phone. if compact, the base height is 29, otherwise it's 49 2) is there a notch/home indicator on the device? if so, need to add the safe area height to the base height 3) is the device a new ipad pro? if so, safe area height is different. so this is not something that you probably want to actually handle yourself. i think it is worth adding an option to the tab navigator that allows you to pass in a callback for when the height is available / when it changes. |
@satya164 - maybe useful for material-bottom-tabs and top-tabs too |
I think currently if you use the Regarding the use case of getting the height for positioning something above it, I'd advise against that because layout is async, so whatever you want to render won't be rendered correctly before the callback is called. I'd do something like: tabBarComponent: props => (
<View>
<SomethingAbsolute />
<TopTabBar {...props} />
</View>
); |
I think in the worst case where you want the tab bar and the overlay to be rendered at the same time there will be a frame or so of delay, wouldn't be ideal yeah. If you're going to animate it in or show it at any time after the initial render of the tab bar it's not a bad compromise though |
Found a way to solve this, using I created the following connected TabBar component. I could not pass
I could then access the layout/measurement in the absolutely positioned component through the Redux state, and calculate its y position ( |
@draperunner Thanks a lot for posting this solution! I was trying to avoid having to duplicate this logic everywhere that needed the TabBar height for keyboard avoidance calculations. While I'd really like to see this make its way into the library, this is a pretty good solution for keeping track of the state of the Tab Bar's dimensions for now. I'll Likely end up doing the same thing to get the height of the HeaderBar for Stack Navigators. Thanks again! |
Is there an ETA on this? |
no |
"How could you @brentvatne . You have the map to the haven and never show us the way." |
@draperunner I rewrote your solution using React Context import React, { Component } from 'react';
import { View, LayoutChangeEvent, LayoutRectangle } from 'react-native';
import { BottomTabBar, BottomTabBarProps } from 'react-navigation';
interface State {
layout: LayoutRectangle;
}
const initialValue = {
x: 0,
y: 0,
width: 0,
height: 0,
};
const TabBarContext = React.createContext<LayoutRectangle>(initialValue);
export const TabBarProvider = TabBarContext.Provider;
export const TabBarConsumer = TabBarContext.Consumer;
class TabBarComponent extends Component<BottomTabBarProps, State> {
public readonly state = {
layout: initialValue,
};
private setTabMeasurement = (event: LayoutChangeEvent) => {
const {
nativeEvent: { layout },
} = event;
this.setState({
layout,
});
};
public render() {
return (
<TabBarProvider value={this.state.layout}>
<View onLayout={this.setTabMeasurement}>
<BottomTabBar {...this.props} />
</View>
</TabBarProvider>
);
}
}
export { TabBarComponent }; import React, { ReactNode } from 'react';
import { ScrollView, ScrollViewProps } from 'react-native';
import { TabBarConsumer } from './TabBarComponent';
export const TabBarAwareScrollView = ({
children,
...props
}: ScrollViewProps & { children: ReactNode }) => {
return (
<TabBarConsumer>
{tabBarLayout => (
<ScrollView
{...props}
contentContainerStyle={{
paddingBottom: tabBarLayout.height,
}}
>
{children}
</ScrollView>
)}
</TabBarConsumer>
);
}; |
Forgive my poor English.Forgive me for using Google Translator. ` getHeaderHeight(event) `<View style={{ flex: 1 }} onLayout={this.getContentHeight}> getContentHeight(event) So~ let bottomBarHeight = height - this.headerHeight - this.contentHeight;` |
In
https://reactnavigation.org/docs/en/bottom-tab-navigator.html |
This issue appears to be no longer valid |
@osdnk is there a final solution to do what is proposed in this issue? |
I came with solution without context etc. import React from 'react';
import { View } from 'react-native';
import { BottomTabBar } from 'react-navigation-tabs';
import { BottomTabBarProps } from 'react-navigation-tabs/lib/typescript/src/types';
// layout is stored as module variable
let tabBarLayout = {
x: 0,
y: 0,
width: 0,
height: 0,
};
// there is exported way to get current tabbar height
export function getTabBarHeight() {
return tabBarLayout.height;
}
// there is simple tab bar component used when creating navigator that will update this layout
export function TabBarComponent(props: BottomTabBarProps) {
return (
<View
collapsable={false}
onLayout={(event) => {
tabBarLayout = event.nativeEvent.layout;
}}
>
<BottomTabBar {...props} />
</View>
);
} Later on, I simply use this component, when creating navigator const HomeScreenTabs = createBottomTabNavigator(
{
...calendarRoutes,
...taskScreenRoutes,
},
{
tabBarComponent: TabBarComponent,
); and then, I can just get tabbat height anywhere using exported |
Huge if true, @domingogogo |
Default height is 49. Search for the DEFAULT_HEIGHT in below link: |
Modern solutions in React Navigation 5 (from documentation: https://reactnavigation.org/docs/bottom-tab-navigator/)
Or you can use:
|
using:
UPDATE: |
Hey, I'm using version |
This worked for me, Thanks a lot ! |
react hook solution:
|
I spent hours on this and here's some gotchas associated with this. I should note that in my context, I was specifically using the materialNavBar, and I found the documentation to be terrible, and couldn't find another more useful thread.
import React from "react";
import { useSafeAreaInsets } from "react-native-safe-area-context";
export default function useMaterialNavBarHeight() {
const { bottom } = useSafeAreaInsets();
const tabBarHeight = bottom + 64;
return tabBarHeight;
} Then in a component where you need the navbar height, you can just do. function someComponent(){
const navBarHeight = useMaterialNavBarHeight()
} |
Hey! This issue is closed and isn't watched by the core team. You are welcome to discuss the issue with others in this thread, but if you think this issue is still valid and needs to be tracked, please open a new issue with a repro. |
Are you sure? 64 + insets.bottom gives 98 on iPhone X, that sounds totally wrong. |
You probably meant 54 instead ;) |
You may very well be right. I think I took |
Yeah sometimes 10px doesn't really show itself, here's one demonstration : I tested it on iPhone X using the debug inspect element it's 88 pixels, insets.bottom is 34 therefore 54 is exactly right for iPhone X. Here's the full code I wrote for both default and material versions: //this part is picked from a stackoverflow issue.
const getDefaultHeaderHeight = (orientation: Orientation) => {
const majorVersion = parseInt(<string>Platform.Version, 10);
const isIos = Platform.OS === "ios";
const isIOS11 = majorVersion >= 11 && isIos;
// @ts-ignore
if (Platform.isPad) return 49;
if (isIOS11 && orientation === Orientation.portrait) return 49;
return 29;
};
export const useBottomTabBarHeight = () => {
const {orientation, insets} = useSomeHookWhichWouldGetOrientationAndInsetsForYouSorryICouldNotShareMine();
let type = BOTTOM_NAVIGATOR_TYPE.DEFAULT;
if (Platform.OS === "android") {
type = BOTTOM_NAVIGATOR_TYPE.MATERIAL;
}
if (type === BOTTOM_NAVIGATOR_TYPE.DEFAULT) {
return getDefaultHeaderHeight(orientation) + insets.bottom;
} else if (type === BOTTOM_NAVIGATOR_TYPE.MATERIAL) {
//based on https://stackoverflow.com/a/60895652/10268067
return 54 + insets.bottom;
}
}; usage :
|
There is a new library which works like a charm https://github.com/ConnectyCube/react-native-android-navbar-height
|
I'm trying to get the height of the bottom tab bar so that I know how to absolutely position a component above it without that component being cut off.
The text was updated successfully, but these errors were encountered: