Oops!!

プログラミングとかのラフなブログ

React Navigationでモーダルを使用した時のTOPからの高さを取得する

React Navigationでモーダルを使用した時のTOPからの高さを取得する

React Navigationを使用していて、要素のサイズを取得する際にどこにその値が格納されているのかよくわからなかったので、備忘録としてまとめました。

特にモーダルを使用しているアニメーションにより高さが変わるので、なかなか厄介でした。

以下の画像とコードをベースとして①から順番に取得方法を記述していきます。

今回はiOSでしか作成していないので、Androidについては未確認です。

参考画像

サンプルコード

import React from 'react'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { StatusBar, StyleSheet } from 'react-native'
import { NavigationContainer } from '@react-navigation/native'
import { createNativeStackNavigator } from '@react-navigation/native-stack'
import ModalNavigation from './src/ModalNavigation'
import 'react-native-gesture-handler'

const MainStack = createNativeStackNavigator<MainStackParamList>()

function IndexScreen () {
  return <View><Text>Index</Text></View>
}

function ModalScreen () {
  return <View><Text>Modal</Text></View>
}

function ModalNavigation () {
 return (
  <MainStack.Navigator initialRouteName="Index">
    <MainStack.Group>
      <MainStack.Screen name="Index" component={IndexScreen} />
    </MainStack.Group>
    <MainStack.Group screenOptions={{ presentation: 'modal' }}>
      <MainStack.Screen name="Modal" component={ModalScreen} />
    </MainStack.Group>
  </MainStack.Navigator>
 )
}

export default function App () {
  return (
    <SafeAreaProvider style={styles.container}>
      <NavigationContainer>
        <ModalNavigation />
      </NavigationContainer>
      <StatusBar barStyle='dark-content' />
    </SafeAreaProvider>
  )
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: '#fff'
  }
})

StatusBarの高さの取得方法

まずは①の取得方法です。 確認したところ、3つありました。

NativeModulesを使用する

Androidは未確認の方法です。

import { NativeModules } from 'react-native'
const { StatusBarManager } = NativeModules
console.log(StatusBarManager.HEIGHT)

useSafeAreaInsetsを使用する

今回はSafeAreaProviderを使用しているので、それを使って取得します。

import { useSafeAreaInsets } from 'react-native-safe-area-context'
const insets = useSafeAreaInsets()
console.log(insets.top)

StatusBarを使った取得

これはAndroidのみです。

import { StatusBar } from 'react-native'
console.log(StatusBar.currentHeight)

iOSの高さが取得できているので、一番上がおそらく安定してると思います。

StatusBarのボトムから一番表に出ているコンポーネントのヘッダーまでの位置の取得方法

まずはこれは②の取得方法ですが、明確に数字を取れるようなものはありませんでした。 一番上の線と二番目の線の距離を測ると10pxだったので固定でおいています。

react-navigationのgetDefaultHeaderHeightを見るとデバイス毎に決め打ちされてるので、一旦これでいいかなと思っています。

import { useHeaderHeight } from '@react-navigation/elements'
const headerHeight = useHeaderHeight()
console.log(StatusBar.currentHeight + 10)

モーダルが出るときに、スクリーンが背景に隠れる動きをしているので、もしかすると固定ではなくスケールを使ってるかもしれませんが、そこまで調べるのは面倒でした。

プロフィール画像

すずき ゆうた

愛知県でフリーランスのフロントエンド・エンジニアをしています。Reactを用いた開発が得意です。 他にもプロジェクトマネジメントや組織マネジメントも行ってきました。エビデンスのない事でも自分の経験から書いていくので話半分くらいでお願いします。