前回に引き続き、アプリに使用した技術をアウトプットしていきます。
解説する私のアプリはこちら。
わかりすと -勉強サポートアプリ-
NavigationView
階層的な画面遷移を管理するビュー。
NavigationLink
NavigationView内で、__画面遷移を行うトリガーになるビュー__と__遷移先のビュー__の両方を指定できるビュー。NavigationViewとセットで使う。
実際の動作
※拡大推奨
動画のポイント
- NavigationViewの外側の領域は切り替わらず、遷移先にも表示される。(動画内のヘルプボタン)
- 遷移先の画面の左上には、前の画面にもどるためのボタンが表示される。
- もどるボタンにはタイトルがそのまま書かれる。
コード
今回作成したサンプルアプリのソースコードはこちら
まず、一番上の階層から見ていきましょう。
import SwiftUI
struct ContentView: View {
let regions = ["カントー地方", "ジョウト地方", "ホウエン地方", "シンオウ地方"]
var body: some View {
VStack{
// ここから
HStack{
Spacer()
Button(action: {}, label: {
Text("ヘルプ")
})
}
.padding(.horizontal)
// ここまではNavigationViewに含まれない
//ここから
NavigationView {
List(0..<4) { n in
NavigationLink(regions[n], destination: Region(id: n, regionName: regions[n]))
}
.navigationTitle("そらをとぶ")
}
//ここまでがNavigationViewの領域
}
}
}
基本として、__遷移する(切り替わる)のはNavigationViewの{}内の要素だけ__です。上のソースコードの「ヘルプ」というラベルのボタンはNavigationViewに含まれないため、リンクをタップしても切り替わらずに画面上部に残っています(動画を確認してください)。今回の「ヘルプ」ボタンのように、何らかの理由で遷移先にもずっと表示させたいものがある場合はNavigationViewに含めない方が良いでしょう。
次にNavigationViewの中を見ていきます。
NavigationViewの中にはNavigationLinkが書かれており、Listの繰り返し処理で4つ並ぶようにしています。上で説明したとおり、NavigationLinkは画面遷移のトリガーと遷移先のビューを指定できます。今回はregions[n]
(配列regionsのn番目の要素)がトリガー、Regionビュー
が遷移先となっています。
Regionビューのソースコードはこちら。
import SwiftUI
struct Region: View {
let id: Int //地方によって表示を変えるためのプロパティ
let regionName: String //地方の名前をタイトルにするためのプロパティ
var body: some View {
//NavigationViewは書かない
List(0..<4) { n in
NavigationLink(regionsArray[id][n], destination: Flight(city: regionsArray[id][n]))
.navigationTitle(regionName)
}
}
}
//各地方ごとのデータ
let kanto = ["マサラタウン", "トキワシティ", "ニビシティ", "ハナダシティ"]
let joto = ["ワカバタウン", "ヨシノシティ", "キキョウシティ", "ヒワダタウン"]
let hoen = ["ミシロタウン", "コトキタウン", "トウカシティ", "カナズミシティ"]
let shino = ["フタバタウン", "マサゴタウン", "クロガネシティ", "コトブキシティ"]
//idに対応する配列を取り出すための配列
let regionsArray = [kanto, joto, hoen, shino]
ここで見てほしいのは、NavigationLinkはあるのにNavigationViewの記述がどこにも書かれていないことです。NavigationViewは一番上の階層となるビューに書くだけで、遷移先にも機能を持たせることができます。
逆に、下の階層にもNavigationViewを書き、次の画面に遷移するとこのようになります。
画面左上に、前の画面にもどるためのボタンが2つ並んでいることがわかると思います。これはNavigationViewの中にNavigationViewを作っていると判断された結果です。このような表示にしたい場合は別ですが、基本は__一番上の階層にのみNavigationViewを書くことをおすすめします__。
次回はnavigationTitleについて書きます。
参考文献
SwiftUI徹底入門 金田浩明(著)(【注意】Xcode12非対応のものです)