【SwiftUI】NavigationStack


## はじめに
SwiftUIの画面遷移方法として
iOS16から使用できる[NavigationStack](https://developer.apple.com/documentation/swiftui/navigationstack)ついて触れていきたいと思います。




## 動作環境
Xcode 14.2
iOS16

## NavigationLinkのみを使った遷移
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationStack {
            List {
                NavigationLink("Orange") {
                    OrangeView()
                }
                NavigationLink("Red") {
                    RedView()
                }
                NavigationLink("Green") {
                    GreenView()
                }
            }
            .navigationTitle("Colorリスト")
            .navigationBarTitleDisplayMode(.inline)
        }
    }
}

struct OrangeView: View {
    var body: some View {
        ZStack {
            Color(.orange)
            Text("orange")
                .font(.largeTitle)
                .foregroundColor(.white)
        }
    }
}

struct RedView: View {
    var body: some View {
        ZStack {
            Color(.red)
            Text("red")
                .font(.largeTitle)
                .foregroundColor(.white)
        }
    }
}

struct GreenView: View {
    var body: some View {
        ZStack {
            Color(.green)
            Text("green")
                .font(.largeTitle)
                .foregroundColor(.white)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
```
各NavigationStackの中NavigationLinkを記述し、遷移先のViewを呼び出しています。

## pathを使用した遷移
```swift
import SwiftUI

struct ContentView: View {
    @State private var path: [Color] = []

    var body: some View {
        NavigationStack(path: $path) {
            List {
                NavigationLink("Orange", value: Color.orange)
                NavigationLink("Red", value: Color.red)
                NavigationLink("Blue", value: Color.blue)
                NavigationLink("Indigo", value: Color.indigo)
                NavigationLink("Purple", value: Color.purple)
            }
            .navigationTitle("Colorリスト")
            .navigationBarTitleDisplayMode(.inline)
            .navigationDestination(for: Color.self) { color in
                ColorView(path: $path, color: color)
            }
            Button("Yellow + Green") {
                path.append(.yellow)
                path.append(.green)
            }
        }
    }
}

struct ColorView: View {
    @Binding var path: [Color]
    let color: Color

    var body: some View {
        ZStack {
            color
            VStack {
                Text(color.description)
                    .font(.largeTitle)
                    .foregroundColor(.white)
                    .padding()
                Button {
                    path.removeAll()
                } label: {
                    Text("Colorリストに戻る")
                        .foregroundColor(.white)
                }
                Button {
                    path.removeLast()
                } label: {
                    Text("一つ前に戻る")
                        .foregroundColor(.white)
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


```
こちらは`path`変数と、`navigationDestination`モディファイアを使用しています。
画面遷移は`navigationDestination`モディファイアの引数にデータ型と遷移先Viewを渡すことで行います。

また、`path.append(.yellow)`と`path.append(.green)`のように`path`に値を追加することで
`Colorリスト画面`→`(Yellow画面)`→`Green画面`のように画面遷移を行います。このときYellow画面は表示されませんが、Green画面からナビゲーションバーの戻るボタン押下時にはYellow画面に遷移されます。
なお、ColorViewにもpathを渡し、ColorViewから`path`配列の中身をすべて削除するとYellow画面を経由せずにColorリストに戻ることができます。



## 参考

[【SwiftUI】ナビゲーションバー(NavigationStack)の使い方について解説](https://ios-docs.dev/swiftui-navigationstack)
[【SwiftUI】データ駆動型の画面遷移（navigationDestination）](https://capibara1969.com/4074)