36

How do i get the height of the StackNavigator header programmatically?

I need to detect if component A's position is within component B when pan gesture (drag) on A is released. However, the position from onPanResponderRelease's gesture.moveY is measured with respect to the entire screen, whereas the position returned from A's onLayoutis measured with respect to the parent view. So i'd need to know the parent view's current height to reconcile the differences.

Avery235
  • 4,756
  • 12
  • 49
  • 83

5 Answers5

131

React navigation V6

import { useHeaderHeight } from '@react-navigation/elements';
const headerHeight = useHeaderHeight();

React navigation V5

import { useHeaderHeight } from '@react-navigation/stack';
const headerHeight = useHeaderHeight();

or with React Context's API (not recommended)

React navigation V4

import { Header } from 'react-navigation-stack';
const headerHeight = Header.HEIGHT;

React navigation V2-V3

import { Header } from 'react-navigation';
const headerHeight = Header.HEIGHT;

Another answer to this problem

Florent Roques
  • 2,424
  • 2
  • 20
  • 23
  • 1
    This code is not working anymore: https://github.com/react-navigation/react-navigation/issues/2411 – BaHaa Jr. Oct 09 '18 at 18:05
  • 1
    How do we do this in React Nav V5 – SKeney Apr 24 '20 at 04:24
  • 1
    In version 5, there is either `useHeaderHeight` hook, or `HeaderHeightContext` provided by `@react-navigation/stack`. You can find it on this page - https://reactnavigation.org/docs/stack-navigator/ – rdamborsky May 01 '20 at 06:28
  • 1
    Thank you for the v5 version. I'm using this with https://github.com/osdnk/react-native-reanimated-bottom-sheet `snapPoints={[screenHeight - headerHeight, 200]}` – wobsoriano Jun 15 '20 at 01:07
  • 9
    V5 solution gives me this error: `Error: Couldn't find the header height. Are you inside a screen in Stack?` or this: `Error: Invalid hook call. Hooks can only be called inside of the body of a function component...`. – RobiZzT Jul 20 '20 at 13:36
  • The context solution returns `undefined` and the hook solution return the error as RobiZzT stated above. Truth be told this functionality is *really* poorly documented... – Alex Rummel Jul 05 '21 at 15:06
  • 1
    the value of `const headerHeight = useHeaderHeight()` is `0`! – Oliver D Sep 29 '21 at 07:14
  • What about class components? Or do you all assume everyone uses Hooks nowadays? – showtime Apr 13 '22 at 20:36
  • in v6, we need to download a different package for one simple thing (though it provides a lot of other functionalities but styles should have been included). Anyway, on android, header height is nearly 80 dp – Irfan wani May 17 '23 at 05:41
6

For React navigation V6:

you can use this for functional components

import { useHeaderHeight } from '@react-navigation/elements';

and this for both class components and functional components

import { HeaderHeightContext } from '@react-navigation/elements';

// ...

<HeaderHeightContext.Consumer>
  {headerHeight => {
    /* render something and use "headerHeight" in child components*/
  }}
</HeaderHeightContext.Consumer>

Read More from Here

Hamza.am.i
  • 123
  • 1
  • 10
  • 1
    You are rendering a new component there, you are not getting the header height value! Please check what are you posting before you post – showtime Apr 12 '22 at 13:47
3

These are the helpers that I use. getHeaderHeight method gets the correct height in every platform (including iphone x) and orientation:

import { Dimensions, DeviceInfo, Platform } from 'react-native';
import { Header } from 'react-navigation';

export const LANDSCAPE = 'landscape';
export const PORTRAIT = 'portrait';

export const getHeaderHeight = () => {
  let height;
  const orientation = getOrientation();
  height = getHeaderSafeAreaHeight();
  height += DeviceInfo.isIPhoneX_deprecated && orientation === PORTRAIT ? 24 : 0;

  return height;
};

// This does not include the new bar area in the iPhone X, so I use this when I need a custom headerTitle component
export const getHeaderSafeAreaHeight = () => {
  const orientation = getOrientation();
  if (Platform.OS === 'ios' && orientation === LANDSCAPE && !Platform.isPad) {
    return 32;
  }
  return Header.HEIGHT;
};

export const getOrientation = () => {
  const { width, height } = Dimensions.get('window');
  return width > height ? LANDSCAPE : PORTRAIT;
};

https://github.com/react-navigation/react-navigation/issues/2411#issuecomment-382434542

Javier Orellana
  • 400
  • 1
  • 3
  • 7
0

I use measureInWindow() for this.

It takes stack navigator height into account.

RobinBobin
  • 555
  • 7
  • 17
0

This is from the official docs as of today:

import { useHeaderHeight } from '@react-navigation/elements';

// ...

const headerHeight = useHeaderHeight();

This is working well for me in my application.

Link to the docs

Taylor
  • 1
  • 1