Reputation: 577
I'm using NavigationLink
to navigate screens in NavigationView
.
How can I remove screen from navigation stack?
Not just hide the navigation "Back" button but completely remove screen from stack?
For example, I have screen chain like this: A -> B -> C
How can I remove screen B
to go back from C
to A
?
Or, another example, how to remove screen A
and B
, so the C
screen will be the root?
Or all of this is impossible by conception of SwiftUI?
Upvotes: 9
Views: 8217
Reputation: 500
There is a new element in SwiftUI called NavigationStack which lets you manipulate the stack any way you want. I have been playing with it in an example project attempting to use it in a maintainable and programatic approach to coordinators in SwiftUI
Upvotes: 1
Reputation: 52312
In terms of your first question (going from C
to A
), this is often called "popping to root" and has a number of solutions here on SO, including: https://stackoverflow.com/a/59662275/560942
Your second question (replacing A
with C
as the root view) is a little different. You can do that by replacing A
with C
in the view hierarchy. In order to do this, you'd need to have some way to communicate with the parent view -- I chose a simple @State
/@Binding
to do this, but one could use an ObservableObject
or even callback function instead.
enum RootView {
case A, C
}
struct ContentView : View {
@State private var rootView : RootView = .A
var body: some View {
NavigationView {
switch rootView {
case .A:
ViewA(rootView: $rootView)
case .C:
ViewC(rootView: $rootView)
}
}.navigationViewStyle(StackNavigationViewStyle())
}
}
struct ViewA : View {
@Binding var rootView : RootView
var body: some View {
VStack {
Text("View A")
NavigationLink(destination: ViewB(rootView: $rootView)) {
Text("Navigate to B")
}
}
}
}
struct ViewB : View {
@Binding var rootView : RootView
var body: some View {
VStack {
Text("View B")
NavigationLink(destination: ViewC(rootView: $rootView)) {
Text("Navigate to C")
}
Button(action: {
rootView = .C
}) {
Text("Navigate to C as root view")
}
}
}
}
struct ViewC : View {
@Binding var rootView : RootView
var body: some View {
VStack {
Text("View C")
switch rootView {
case .A:
Button(action: {
rootView = .C
}) {
Text("Switch this to the root view")
}
case .C:
Text("I'm the root view")
}
}
}
}
Upvotes: 5