React Navigationで特定のスクリーンだけモーダルにするルーティング設定


ルーティングライブラリ「React Navigation」のcreateStackNavigator()の画面遷移は、iOS,Androidともに標準トランジションが発生する。スクリーンが右からスライドして重なる具合のものだ。

スマホアプリの画面遷移といえばスタンダードなものだが、フェードインで現れるモーダルパターンもある。

これを設定するにはcreateStackNavigator(RouteConfigs, StackNavigatorConfig)のStackNavigatorConfigに該当するオプション設定から行う。

{
  mode: modal,
}

このように画面遷移モードの変更はとても容易い。ところが複数のルーティング中にモーダルスクリーンが混じっていると、ややこしくなる。

このエントリーでは、特定のスクリーンだけモーダルにするルーティング設定を紹介したい。

なにがややこしいか?

createStackNavigator(RouteConfigs, StackNavigatorConfig)のルーティング設定は、RouteConfigsに該当するところにオブジェクト形式で定義する。下記の具合に記述する。

const App = createStackNavigator({
  Home: HomeScreen,
  List: ListScreen,
  Detail: DetailScreen,
});

ルーティング名(Key)と該当コンポーネント(Value)が紐づく形だ。HomeスクリーンにListスクリーンが重なり、Detailスクリーンが重なり画面遷移する。いずれの画面遷移もスクリーンが右からスライドして重なる具合のものだ。

ここにモーダル用のスクリーンを加えて、遷移モードを変更してみるとどうなるだろうか。下記の具合にしてみる。

const AppNavigator = createStackNavigator({
  Home: HomeScreen,
  List: ListScreen,
  Detail: DetailScreen,
  Modal: ModalScreen, // ?
}, {
  mode: modal,
});

想像できただろうか?そう。すべてがモーダル式に画面遷移してしまうわけだ。

解決するには、

モーダル式になるハブの役割をするcreateStackNavigator()を設ければよい。下記の具合に記述する。

RootNavigator

const RootNavigator = createStackNavigator({
  App: AppNavigator,
  Modal: ModalNavigator,
}, {
  mode: modal,
  headerMode: 'none',
});

AppNavigator

const AppNavigator = createStackNavigator({
  Home: HomeScreen,
  List: ListScreen,
  Detail: DetailScreen,
});

ModalNavigator

const ModalNavigator = createStackNavigator({
  Modal: ModalScreen,
});

それぞれ定数に定義したのは可読性を懸念してのことだけれど、いっきに記述することもできる。下記の具合だ。

const RootNavigator = createStackNavigator({
  App: createStackNavigator({
    Home: HomeScreen,
    List: ListScreen,
    Detail: DetailScreen,
  }),
  Modal: createStackNavigator({
    Modal: ModalScreen,
  }),
}, {
  mode: modal,
  headerMode: 'none', // ?
});

つまりモーダル式のcreateStackNavigator()に、スライド式のcreateStackNavigator()を内包するような装いになる。これによってHome,List,DetailスクリーンのいずれからもModalスクリーンを開くことができるわけだ。

そしてheaderMode: 'none',は、タイトルバーを表示しない旨の指定だ。内包した先のcreateStackNavigator()でタイトルバーを設ける都合上、大枠のタイトルバーを非表示にしないと二重にタイトルバーが出現してしまう。

まとめ

特定のスクリーンだけモーダルにするルーティング設定の紹介だった。

モーダルといえば、UIフレームワークに用意されているものもある。<Modal />のようなものを利用するならば遷移モードを変更しなくてよいのだが、そのモーダルはタイトルバーを覆わない。スクリーンコンポーネントがタイトルバーより下層レイヤーに位置するからと想像できる。結局、ルーティングで解決しなければならないのかもしれない。

このエントリーが、あなたのクリエイティビティを刺激するものであると期待したい。


Leave a Reply

Your email address will not be published. Required fields are marked *