iOS 16, SwiftUI 4
NavigationStack
If you are going to support iOS 16 and above, you can use the benefits that NavigationStack is offering.
You can see it as a stack that can push your views into. So it will be so easier to navigate a user through the app.
If this is our detailed view that we want to move here:
struct DetailView: View {
var body: some View {
Text("You are at detail view")
}
}
First approach is By using the NavigationLink
like before. We can move to a new view.
struct ContentView: View {
var body: some View {
NavigationStack {
VStack {
NavigationLink {
DetailView()
} label: {
Text("Show Detail")
}
}
.navigationTitle("Navigation")
}
}
}
The second approach will use the value
inside the NavigationLink
.
You can pass a value and then define .navigationDestination
based on value types. as soon as user trigger that link SwiftUI will know which navigationDestination
should be responsible for handling that.
struct ContentView: View {
@State var fruits: [String] = ["", "", "", ""]
var body: some View {
NavigationStack {
VStack(spacing: 20) {
NavigationLink("Navigate: String Value", value: "New Page")
NavigationLink("Navigate: Int Value", value: 1)
ForEach(fruits, id:\.self) { fruit in
NavigationLink(fruit, value: fruit)
}
}
.navigationDestination(for: String.self) { value in
Text("New screen")
Text("Value is String -> \(value)")
}
.navigationDestination(for: Int.self) { value in
Text("New screen")
Text("Value is Integer -> \(value)")
}
}
}
}
Third approach NavigationStack
shows its worth by defining a path. We can define a path and control our navigation based on the type. It will be so much easier to navigate programmatically. We can add views or remove them from the path list. It will also be so helpful when we want to navigate back to the root view by making the path list empty.
struct ContentView: View {
@State var path: [String] = []
@State var fruits: [String] = ["", "", "", ""]
var body: some View {
NavigationStack(path: $path) {
ZStack {
Button("Random fruits") {
let random = fruits.randomElement()!
path.append(random)
}
}
.navigationDestination(for: String.self) { value in
VStack(spacing: 20) {
Text("New screen")
Text("Value is String -> \(value)")
Button("Random fruits") {
let random = fruits.randomElement()!
path.append(random)
}
Button("Back to Root") {
path.removeAll()
}
}
}
}
}
}
