ルーティングライブラリ「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 />のようなものを利用するならば遷移モードを変更しなくてよいのだが、そのモーダルはタイトルバーを覆わない。スクリーンコンポーネントがタイトルバーより下層レイヤーに位置するからと想像できる。結局、ルーティングで解決しなければならないのかもしれない。
このエントリーが、あなたのクリエイティビティを刺激するものであると期待したい。