1
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【SwiftUI】NavigationViewがNavigaitonStackへ(iOS16)

Last updated at Posted at 2022-09-18

iOS16でNavigationStackが追加されNavigationViewがDeprecatedになりました。
対応バージョンの問題もある為、すぐに置き換えという訳に行かないと思いますが、
必要になった時の為に確認しておきましょう。

NavigaitonStackの使い方

基本的な使い方はNavigationViewと同じです。

struct BasicNavigationStackView: View {
    var body: some View {
        NavigationStack{
            List{
                NavigationLink("LinkLabelText", destination: Text("Destination"))
                NavigationLink("LinkLabelText2", destination: Text("Destination2"))
            }
        }
    }
}

このようにNavigationStackでNavigationLinkの含まれるViewを囲います。
見ての通り、簡単なViewであればNavigationViewをそのまま置き換えても動作します。

navigaitonTitleやtoolbarなどもそのまま動きます。

navigationDestination

NvavigationViewと違い遷移先をNavigationLinkと分離させて書く事が出来ます。

struct BasicNavigationStackView: View {
    var body: some View {
        NavigationStack{
            List{
                NavigationLink("LinkLabelText", value: "Destination")
                NavigationLink("LinkLabelText2", value: "Destination2")
            }
            .navigationDestination(for: String.self) { text in
                Text(text)
            }
        }
    }
}

NavigationLinkにはvalue引数に遷移先のViewに渡す値を書き、
navigationDestination Modifierで型を指定し値を受ける形になります。

navigationDestinationと分岐

遷移先が複数ある場合は分岐が必要になります。
当然ですがnavigationDestination内で条件分岐が出来ますし、
valueの型が異なると対応した型のnavigationDestinationに振り分けられます。

struct BasicNavigationStackView: View {
    var body: some View {
        NavigationStack{
            List{
                NavigationLink("LinkLabelText", value: "Destination")
                NavigationLink("LinkLabelText2", value: "Destination2")
                NavigationLink("LinkLabelText3", value: 3)
            }
            .navigationDestination(for: String.self) { text in
                if text == "Destination" {
                    Text("Destination")
                }else{
                    Text("Not Destination")
                }
            }
            .navigationDestination(for: Int.self) { value in
                Text("Destination \(value)")
            }
        }
    }
}

注意点

navigationDestinationの優先順位

navigationDestinationは基本的に先に読み込まれたものが優先されます。
同じ型のnavigationDestinationが複数あった場合、後のものは無効になります。

これは画面遷移後であっても同じで、ViewA→ViewB→ViewCと遷移したい時、
同じ型のnavigationDestinationをViewAとViewBに実装しても、
ViewAのnavigationDestinationしか有効になりません。
つまりViewAのnavigationDestinationひとつにViewBとViewCへの遷移を実装しなければなりません。

NavigationStackは2重にしてはいけない

これは初心者にありがちなミスなのですが、
遷移後のViewにもNavigationStackを実装してします事があります。
NavigationViewの頃はデザインがイマイチ良くないものの、とりあえず動きはしました。
NavigationStackの場合は正常に動作しなくなっているので気をつけてください。

ブログ紹介

今回、NavigationStackの基本を紹介しましたが、まだまだ語り尽くせていません。
ブログ記事には補足説明や画面遷移の制御についてなどがあります。

特にNavigationPathを使った画面遷移の制御などは重要ですので、
良ければこちらも確認してみてください。

1
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?