SwiftUIで書かれたコードはAppleのプラットフォームで共通で利用することが出来ます。
(iPhoneでもiPadでもmacOSでもwatchOSでもコンパイルさえ通れば同じコードが動作します)
多くの場合、アプリ開発といえばiPhoneアプリの開発となるのですがSwiftUIにはAppleプラットフォームで共通利用出来るという前提があり考慮しなければいけないことが増えてきます。
本稿ではiPhoneアプリ開発を行う上でのNavigationViewを利用するケースを見ていきたいと思います。
デフォルトの挙動について
以下はシンプルにNavigationViewを利用する実装です。
struct ContentView: View {
var body: some View {
NavigationView {
Text("Hello")
}
}
}
SwiftUIはAppleプラットフォーム共通で利用出来るようにするために、NavigationViewはデフォルトでUINavigationControllerの機能の他にUISplitViewControllerの機能を持っています。
実装を以下のように変更し、iPhoneとiPadでの表示を見てみると違いが確認出来ます。
struct ContentView: View {
var body: some View {
NavigationView {
Text("Primary")
Text("Secondary")
}
}
}
画面の向き | iPhone | iPad |
---|---|---|
縦 | ||
横 |
このように画面の横幅によって表示される内容が異なってくることが確認出来ます。
尚、iPhoneは12 pro maxを利用していますが、iPhone12 miniのようにサイズの小さい端末だと横向きの場合も縦向きの場合も同じ表示になります。
NavigationLinkの挙動
NavigationLinkを利用する場合の挙動は以下のパターンに分けられます。
PrimaryのNavigationLink | SecondaryのNavigationLink | |
---|---|---|
画面の横幅(小) | Primaryに対して次の画面がPushされる | 表示されることはない |
画面の横幅(大) | Secondaryの内容が変わる | Secondaryに対して次の画面がPushされる |
UISplitViewControllerを無効化する
上記内容を踏まえると横向きにしたケースで端末のサイズによって挙動が変わってくるiPhoneの場合、画面が分割されるケースとそうでないケースで見せ方を考える必要が出てきてしまうため実装難易度が高くなります。
これを回避するために、SplitViewを無効化するオプションがあります。
navigationViewStyle
というmodifierを利用して、NavigationViewの挙動を変更することが出来ます。
NavigationViewはデフォルトではDoubleColumnNavigationViewStyle
を設定しているような振る舞いをします。
navigationViewStyle
の引数にStackNavigationViewStyle
を設定することでUISplitViewControllerの設定を無効化し、画面の表示を統一することが出来ます。
struct ContentView: View {
var body: some View {
NavigationView {
Text("Primary")
Text("Secondary")
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
上記のように設定すると画面のサイズがどうなってもSecondaryViewが表示されなくなり、画面サイズによる挙動が統一されます。
iPhoneでSwiftUIを利用する場合、UISplitViewControllerが無効になっていないと他にも問題が出たりするので安定した開発をするためにもNavigationViewにはStackNavigationViewStyle
を設定しておくのが無難です。