SwiftUI에서 NavigationStack
을 사용하는 방법은 세가지가 있다.
NavigationStack
과 NavigationLink
사용하기NavigationStack
과 NavigationLink
, NavigationDestination
사용하기NavigationStack
과 NavigationPath
, NavigationDestination
사용하기각각의 사용법과 차이점을 알아본다.
또한 NavigationPath
를 사용해서 NavigationStack
의 state를 관리하는 방법을 알아본다.
해당 포스트 내용은 iOS 16.0 이상에만 해당합니다.
NavigationStack
의 init(root:)
의 root view에 NavigationLink(destination:label:)
를 넣어준다.import SwiftUI
struct FirstExample: View {
var body: some View {
NavigationStack {
VStack {
Text("Root View").font(.title)
NavigationLink {
NextView()
} label: {
Text("See Next View")
}
}
}
}
}
struct NextView: View {
var body: some View {
Text("Next view")
}
}
NavigationLink
의 initializer 내부로 넣지 않고 따로 빼는 방법도 있다.NavigationLink
의 init(_:,value:)
와 .navigationDestination(for:destination:)
view modifier을 사용하는 방법이다.NavigationStack
에 link의 value
를 제공하는 방식이다..navigationDestination(for:destination:)
는 value의 타입에 따라서 navigation destination view를 정해주는 view modifier이다.Hashable
한 타입만 제공이 가능하다. 따라서 custom type을 value로 제공하고자 하면 Hashable을 준수해야한다.import SwiftUI
struct ContentView: View {
var body: some View {
NavigationStack {
VStack {
Text("Root View").font(.title)
NavigationLink("See Next view", value: "next view")
}
.navigationDestination(for: String.self) { string in
if string == "next view" {
NextView()
}
}
}
}
}
struct NextView: View {
var body: some View {
Text("Next view")
}
}
NavigationStack
에 제공하는 value의 타입이 다양하다면, stack의 state를 관리하기 위해 NavigationPath
를 이용한다.NavigationLink
로 view를 감싸는 대신 NavigationPath
에 value를 append한다.NavigationLink
와 마찬가지로 .navigationDestination(for:destination:)
view modifier를 사용해서 destination view를 지정한다.Hashable
해야한다.import SwiftUI
struct ContentView: View {
@State var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
VStack {
Text("Root View").font(.title)
Button(action: {
path.append("next view")
}, label: {
Text("See Next view")
})
}
.navigationDestination(for: String.self) { string in
if string == "next view" {
NextView(path: $path)
} else if string == "next next view" {
NextNextView()
}
}
}
}
}
struct NextView: View {
@Binding var path: NavigationPath
var body: some View {
Button(action: {
path.append("next next view")
}, label: {
Text("See Next next view")
})
}
}
struct NextNextView: View {
var body: some View {
Text("Next next view")
}
}
NavigationPath
를 사용할 수 있다.import SwiftUI
struct ContentView: View {
@State var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
VStack {
Text("Root View").font(.title)
Button(action: {
path.append("next view")
}, label: {
Text("See Next view")
})
}
.navigationDestination(for: String.self) { string in
if string == "next view" {
NextView(path: $path)
} else if string == "next next view" {
NextNextView(path: $path)
}
}
}
}
}
struct NextView: View {
@Binding var path: NavigationPath
var body: some View {
Text("Next View").font(.title)
Button(action: {
path.append("next next view")
}, label: {
Text("See Next next view")
})
}
}
struct NextNextView: View {
@Binding var path: NavigationPath
var body: some View {
Text("Next next view").font(.title)
Button {
while path.count > 0 {
path.removeLast()
}
} label: {
Text("Back to root view")
}
}
}