0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【iOS】NavigationStack周りを整理してみた

Posted at

NavigationStack周りがよくわからなかった件

この2年間ほどAndroidエンジニアとして仕事してきましたが、急な異動(?)によりAndroidからiOSエンジニアになることに......。
とりあえずSwift, SwiftUiから勉強し始めましたが、その際にNavigationStackの使い方がいまいち整理つかなかったのでここで整理しようかなと思います。
(Androidエンジニアから転身したばかりですので、あまり詳しいことは書けない/抽象的な表銀が多くなりそうですが......)

そもそもNavigationStackとは?

NavigationStackはiOS16以降で使用できるようになった、画面遷移用のコンポーネント。
画面遷移はこれでできますよ、という代物。

NavigationStack 基本系

import SwiftUI

struct ScreenA: View {
    var body: some View {
        NavigationStack {
            NavigationLink("Go to ScreenB") {
                ScreenB()
            }
        }
    }
}

struct ScreenB: View {
    var body: some View {
        Text("Screen B")
    }
}

NavigationStackを宣言した後に、NavigationLinkを置き、中に遷移先のviewを配置します。
NavigationLinkにStringを渡していると、この文字列をタップした時に画面遷移が行われるようになります。
便利ですね。

変化形

基本形を少し変えて応用してみます。
例えばリストを表示して、選択したコンテンツに応じて次の画面で表示するものを変化させたい時は以下の様にします。

struct ScreenA: View {
    var body: some View {
        NavigationStack {
            List(["Apple", "Banana", "Cherry"], id: \.self) { item in
                NavigationLink(value: item) {
                    ViewContentsA(text: item)
                }
            }
            .navigationDestination(for: String.self) { item in
                ScreenB(text: item)
            }
        }
    }
}

struct ScreenB: View {
    var text: String
    var body: some View {
        Text(text)
    }
}

struct ViewContentsA: View {
    var text: String
    var body: some View {
        VStack {
            Text(text)
        }
        .padding()
        .border(Color.black, width: 2)
    }
}

NavagationStackにはListをおき、Listのラムダの中でNavigationLinkを置きます。
NavigationStackの中に遷移元の画面を置くようなイメージですね。
この時、NavigationLinkには引数valueを渡します。
NavigationLinkのラムダにはリストとして表示したいviewを設置します。

そしてListに.navigationDestination(for:)を設定します。
.navigationDestination(for:)を使うことで、先ほどはNavigationLinkに直接渡していた遷移先のviewを定義することができます。
.navigationDestinationの引数forとNavigationLinkの引数valueの型は一致させてください。
画面遷移ができなくなります。

あと、.navigationTitle() を使うことでタイトルをつけることもできます。
呼び出しもとにつけておけば遷移先のViewにも表示されます。

 NavigationStack {
            List(["Apple", "Banana", "Cherry"], id: \.self) { item in
                NavigationLink(value: item) {
                    ViewContentsA(text: item)
                }
            }
            .navigationDestination(for: String.self) { item in
                ScreenB(text: item)
            }
            .navigationTitle("Fruits")
        }

ざっくりまとめ

  • 画面遷移ではNavigationStackとNavigationLinkを使う
  • 最初にNavigationStackを宣言、NavigationStackの中には画面遷移元のViewを配置するイメージ
  • NavigationLinkで画面遷移のためにタップするUI(ボタンなど)を定義する
  • .navigationDestinationで遷移先のviewを紐づける

正直最初はこのあたりがごちゃごちゃになってました、、、、、、
実はもう少し凝った使い方もできるようなのですが、追々試していければなと思っています。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?