Help us understand the problem. What is going on with this article?

react-navigationとreact-native-orientationを組み合わせて特定のページの画面向きを固定する

More than 3 years have passed since last update.

実現したいこと

  • react-navigationを使ったアプリで特定のページのみ画面を横向き固定にしたい
  • 戻るボタンで戻ってきたような場面でもちゃんと指定した通りに固定させたい

実現方法

react-native-orientationのメソッド

  • lockToPortrait()
    • 縦向きにロックする
  • lockToLandscape()
    • 横向きにロックする
  • lockToLandscapeLeft()
    • 左辺が下に来るように横向きにロックする
  • lockToLandscapeRight()
    • 右辺が下に来るように横向きにロックする
  • unlockAllOrientations()
    • ロックを解除する

react-navigationとの連携

  • 遷移の度に呼ばれるonNavigationStateChangeを活用してページ遷移ごとに処理をはさむ
  • 横向き固定にしたい画面のリストを持っておき、リストに含まれる画面に遷移した場合画面をロックする

サンプル

  • A->B->Cの順に遷移する3つのページがある
  • AとCは縦固定、Bは横固定にするサンプル
index.ios.js/index.android.js
import React from 'react';
import { AppRegistry } from 'react-native';
import AppNavigator from './app/navigators/AppNavigator';
import { onNavigationStateChange } from './app/utils/Utils';

// onNavigationStateChange属性に渡した関数はページ遷移が行われるたび(=stateが更新される度)に呼ばれます
const ReactNativeSample = () => <AppNavigator onNavigationStateChange={onNavigationStateChange} />

AppRegistry.registerComponent('ReactNativeSample', () => ReactNativeSample);
app/navigators/AppNavigator.js
import { StackNavigator } from 'react-navigation'
import SampleAScreen from '../containers/SampleAScreen'
import SampleBScreen from '../containers/SampleBScreen'
import SampleCScreen from '../containers/SampleCScreen'

const AppNavigator = StackNavigator({
  SampleA: { screen: SampleAScreen },
  SampleB: { screen: SampleBScreen },
  SampleC: { screen: SampleCScreen },
})

// 横向き固定したい画面リスト
export const landscapeOrientationScreens = ['SampleB']
export default AppNavigator
app/utils/Utils.js
import Orientation from 'react-native-orientation';
import { landscapeOrientationScreens } from '../navigators/AppNavigator';

const handleOrientation = (currentRouteName) => {
  // 受け取った引数が横向き固定したいリストに含まれていたら横向きにロック、そうでなかったら縦向きにロック
  landscapeOrientationScreens.includes(currentRouteName) ?
    Orientation.lockToLandscapeLeft() :
    Orientation. lockToPortrait();
}

// ページ遷移する度に呼ばれる
export const onNavigationStateChange = (prevState, currentState) => {
  const routes = currentState.routes;
  const currentRouteName = routes[routes.length - 1].routeName;
  // 遷移後の画面名を引数に渡す
  handleOrientation(currentRouteName);
}
  • こんな感じで画面Bだけ横向き固定されている

orientation.gif


追記

  • このサンプルだと最初のページで画面固定がきいていなかった
  • index.android.js, index.ios.jsのcomponentWillMountにOrientation. lockToPortrait()を書いておけば対応できる
ozaki25
mdc
”自己研鑽のサイクル”を応援するコミュニティです。外の世界に発信&フィードバックを受け、コミュニティの仲間と共に頑張りましょう。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away