SwiftUIではNavigationViewを使用して階層的な画面遷移を実装することができます。 例えばデータの一覧画面から詳細画面を呼び出したい場合、NavigationView、NavigationLink、Listなどを組み合わせ目的の動作を実現することができます。

iOS 16以降の環境ではNavigationViewは非推奨とされ、NavigationStackへの移行が推奨されていますが、既存のコードを読まなければならない場合などに、NavigationViewの知識があれば役に立ちます。

以下、具体的な使用方法を説明します。

最もシンプルなNavigationView

NavigationViewの使い方は簡単で、目的の要素を囲むだけです。

struct SimpleNavi: View {
    var body: some View {
        NavigationView {
            List {
                Text("リンゴ")
                Text("ぶどう")
                Text("なし")
                
            }
        }
    }
}

実行結果です。

ただし、単に囲んだだけでは外観は変わらず意味がありません。

他の画面への遷移

NavigationViewとNavigationLinkを組み合わせることで、他の画面へ遷移することができます。NavigationLinkの引数destinationで遷移先のビューを指定し、呼び出し元の要素を囲います。

struct NavLink: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: SecondView()) {
                    Text("次の画面を呼び出す")
            }
        }
    }
}

実行結果です。

「次の画面を呼び出す」をタップするとSecondViewが表示されます。呼び出し先の画面であるSecondViewには元の画面に戻るためのリンクが自動的に追加されます。

呼び出し元の画面でNavigationViewを追加し忘れると繊維できません。

Listの項目をタップして他の画面へ遷移

NavigationViewとListとNavigationLinkを組み合わせ、Listの各項目をタップして他の画面へ遷移することもできます。一覧画面から詳細画面を表示するといったよくある画面の流れを作ることができます。

struct NavList: View {
    let persons = ["田中", "佐藤", "山田"]
    var body: some View {
        NavigationView {
            List {
                ForEach(persons, id: \.self) { person in
                    NavigationLink(destination: DetailView(name: person)) {
                        Text(person)
                    }
                }
            }
        }
    }
}

struct DetailView: View {
    var name: String
    var body: some View {
        Text(name)
    }
}

実行結果です。

タップした項目の情報を次の画面に渡して表示することができます。この場合は文字列を渡しているだけですが、書く項目に紐付けられたオブジェクトを渡せば複雑な情報のやりとりも可能となります。

タイトルを指定する

navigationTitleモディファイアを指定しタイトルを設定することができます。同時にnavigationBarTitleDisplayModeモディファイアを指定するとそのタイトルのスタイルを変更することがだできます。どちらもNavigationViewではなく、その内側の要素に指定する必要があります。

struct NavTitle: View {
    var body: some View {
        NavigationView {
            List {
                Text("リンゴ")
                Text("ぶどう")
                Text("なし")
                
            }
            .navigationTitle("くだもの")
            //ラージ
            .navigationBarTitleDisplayMode(.large)
            //インライン
            .navigationBarTitleDisplayMode(.inline)
            //自動
            .navigationBarTitleDisplayMode(.automatic)
        }
    }
}

実行結果です。

.large(デフォルト)

大きなタイトルが表示されます。

.inline

小さめのタイトルです。

.automatic

前のナビゲーションアイテムから継承し自動で決まるスタイルです。