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")
}
}
}