はじめに
SwiftUIの画面遷移には、NavigationView 、NavigationLink、NavigationStack、navigationDestination を使用するかと思います。
基本は NavigationStack、navigationDestination による画面遷移方法が主流かと思いますが、iOS15未満のバージョンを網羅することから、NavigationViewを使用することもあるかと思います。
今回は、SwiftUIの画面遷移を整理してみたいと思います。
NavigationLink を使った書き方(iOS 15未満)
はじめに NavigationLink(destination:,isActive:) を使った書き方です。
struct ContentView: View {
@State private var isActive = false
var body: some View {
NavigationView {
VStack {
Button("次の画面へ") {
isActive = true
}
NavigationLink(
destination: SecondView(),
isActive: $isActive
) {
EmptyView()
}
}
.navigationTitle("最初の画面")
}
}
}
struct SecondView: View {
var body: some View {
Text("次の画面に移動しました。")
.navigationTitle("次の画面")
}
}
上記では、Button をタップして isActive を true にすることで、NavigationLink に設定された画面遷移が行われます。
今回は Button を押したら画面遷移して欲しいため、NavigationLinkのlabel: には EmptyView()を置いておきます。
NavigationStack と navigationDestination を使った書き方(iOS 16以降)
次は、NavigationStack と navigationDestination を使った書き方です。
struct ContentView: View {
@State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
Button("次の画面へ") {
path.append(0)
}
.navigationTitle("最初の画面")
.navigationDestination(for: Int.self) { _ in
SecondView()
}
}
}
}
struct SecondView: View {
var body: some View {
Text("次の画面に移動しました。")
.navigationTitle("次の画面")
}
}
NavigationStack では、path に値を追加することで画面遷移できます。
その値を navigationDestination で受け取り、表示するViewを指定します。
今回はSecondView以外の遷移先はありませんが、appendする値によって遷移先を変えたりする実装にもできます。
両方に対応するためのカスタムViewの書き方
これまでは単体での実装を行なってきましたが、OSが15未満のものをサポートしたいパターンなどもあると思います。
その場合は、カスタムViewを作成して対応することも可能です。
struct CustomNavigation<Content: View>: View {
let content: () -> Content
var body: some View {
if #available(iOS 16.0, *) {
NavigationStack {
content()
}
} else {
NavigationView {
content()
}
}
}
}
struct ContentView: View {
var body: some View {
CustomNavigation {
// 実際の画面遷移処理
}
}
}
上記のようにすることで、ContentView 側で NavigationView と NavigationStack の分岐を書かずに済みます。
まとめ
今回はSwiftUIの画面遷移について、NavigationLink(destination:isActive:) と、NavigationStack / navigationDestination を使った書き方を整理しました。
比較のために NavigationView を使った実装も紹介しましたが、iOS 15以下をサポートする必要がない場合は、基本的に NavigationStack を使った実装で問題ないと思います。
新規実装では NavigationStack を基本にしつつ、既存実装の改修や対応OSの都合がある場合は、NavigationView を使った実装との差分を踏まえて選択するのがよさそうです。