iOS16.0,macOS13.0から使用できるナビゲーションAPI.
既存のNavigationViewを置き換えるView.
既存のNavigationViewと使い方は似ている.
NavigationViewと比べるとNavigationDestinationの位置が変わる.
enum Route: String, Identifiable, CaseIterable {
case A, B, C
var id: Int {
self.hashValue
}
}
struct ContentView: View {
var body: some View {
NavigationStack {
List(Route.allCases) { route in
NavigationLink(route.rawValue, value: route)
}
.navigationTitle("Route")
.navigationDestination(for: Route.self) { route in
SubView()
}
}
}
}
struct SubView: View {
var body: some View {
List(Route.allCases) { route in
NavigationLink(route.rawValue, value: route)
}
}
}
NavigationStack内のViewにあるnavigationDestinationモディファイアでNavigationStackにpushされるViewを作成する.
pushされたViewの中でもNavigationLink(_:, value: x)とすることで親ViewのnavigationDestinationが発火する.
注意としてContentView.navigationDestination(...){ ContentView() }のようにNavigationStackを入れ子にはできない.
NavigationStackのイニシャライザには型消去型のpath: Binding<NavigationPath>を指定することができる.
pathを操作することでナビゲーションをプログラムから遷移させることができる.例えばアプリ終了時にpathを保存して,起動時に復元させるなど.
struct ContentView: View {
@State var path: [Route] = []
var body: some View {
NavigationStack(path: $path) {
List(Route.allCases) {
NavigationLink($0.rawValue, value: $0)
}
.navigationTitle("Route")
.navigationDestination(for: Route.self) { route in
switch route {
case .A:
SubView()
default:
// ナビゲーションスタックをすべて削除する
Button("pop", action: {
path.removeAll()
})
}
}
}
}
}
NavigationSplitViewはiPadOSやmacOSで使用しやすいマスター・ディテールのUIを提供する.
iPadOS.macOSで使用しやすいとしているが,iOSやwatchOSで使用できない訳では無い.画面が小さいOSでは自動的に階層化の処理が行われる.
使用方法は次のようにMasterViewでDetailViewに表示させる種別を選択する形式を提供する.
struct ContentView: View {
@State var selectedRoute: Route?
var body: some View {
NavigationSplitView {
List(Route.allCases, selection: $selectedRoute) { route in
NavigationLink(route.rawValue, value: route)
}
.navigationTitle("Route")
} detail: {
if let selectedRoute {
Text("Select: \(selectedRoute.rawValue)")
}
else {
Text("Select a route")
}
}
}
}
NavigationStackの入れ子はできなかったがNavigationSplitViewのdetailにはNavigationStackを使用することができる.