[SwiftUI]iPad上でNavigaitonViewでSplitViewを実現
SwiftUIでSplitViewを表現する方法がNavigationでできるようなのでまとめます。
少しトリッキーなコードになりますが、少ないコードでSplitViewレイアウトを実装することができます。
検証環境
- Xcode 11.4
Split Viewとは?
設定アプリのように、Viewが2つ並びで左右に別れているレイアウトです。
設定アプリでは、左側のペインに設定項目が並び、それらをタップすると右側ペインに詳細画面が表示されます。
NavigationViewでSplitView
SwiftUIではNavigationViewでSplitViewを表現できるようです。
NavigationView {
NavigationLink(destination: Text("Detail")) { // ③
Text("Master") // ①
}
.navigationBarTitle("Nav", displayMode: .large)
Text("First Screen") // ②
}
.padding(0.5)
NavigationViewに2つの子View、NavigationLinkとTextを入れています。
そして、ここが大事ですが、NavigationViewに対して.padding(0.5)をつけるとiPadにてSplit Viewが表示されます。
paddingは0.5以上だと効きます。
iPadで実行した際のキャプチャがこちらです。コードの①と②が対応しています。

ちなみに「Master」のラベルをタップすると左側のペインがコードの③、destinationのViewに遷移します。

iPhoneで実行するとSplit Viewにはならず、おなじみのスタック型のNavigation Viewになります。コード上の②、NavigaitonViewの二番目の子Viewは無視されます。

paddingがない場合
paddingがない場合どうなるでしょうか?
NavigationView {
NavigationLink(destination: Text("Detail")) { // ③
Text("Master") // ①
}
.navigationBarTitle("Nav", displayMode: .large)
Text("First Screen") // ②
}
//.padding(0.5)
paddingをコメントアウトしてiPadで実行します。

②のViewが全面に表示され、左上のNavボタンをタップすると左横から①のViewがスライドインします。
①のリンクをタップすると右側のViewがリンク先、③のViewに変更されるという動きをするようです。
iOS 13.0で実行すると
iOS 13.0で実行するとNavigationLinkのリンクが効かない現象が起こりました。
リンクが灰色になってタップできない状態になります。

おそらくiOS 13.0のバグです。
まとめ
SwiftUIでNavigationViewによるSplit Viewの方法を紹介しました。
まさかpaddingのありなしでレイアウトが変わるとは思いもしませんでした。
ちょっとトリッキーなのでチーム開発の際はコメントで補ったほうがいいかもしれません。
ただiPadのみSplitViewのレイアウトにしたいという場合はコード量が圧倒的に少なくて表現できるので便利だと思います。
宣伝
インプレスR&D社より、「1人でアプリを作る人を支えるSwiftUI開発レシピ」発売中です。
「SwiftUIでアプリを作る!」をコンセプトにSwiftUI自体の解説とそれを組み合わせた豊富なサンプルアプリでどんな風にアプリ実装すればいいかが理解できる本となっています。
iOS 14対応、Widgetの作成も一章まるまるハンズオンで解説しています。
SwiftUIを学びたい方、ぜひこちらのリンクをチェックしてください!
https://nextpublishing.jp/book/12491.html
