So I have a problem regarding NavigationView and NavigationLinks in SwiftUI while trying to pop the current screen, which is not working in this case.
I have 3 Screens A -> B -> C
Each screen has a button for popping itself.
The pop from B -> A works, but when you navigate from A -> B -> C, the pop from C -> B it’s not working.
Do you know what would be the problem? I will attach the code below and a video.
The app should support iOS 14.
struct ScreenA: View {
@State private var showB = false
var body: some View {
NavigationView {
VStack {
Button("Go to B") {
showB = true
}
NavigationLink(destination: ScreenB(didTapGoBack: {
showB = false
}), isActive: $showB) {
EmptyView()
}
}
}
}
}
struct ScreenB: View {
var didTapGoBack: () -> Void
@State var showC = false
var body: some View {
VStack {
Button("Go to C") {
showC = true
}
Button("Back to Screen A") {
didTapGoBack()
}
NavigationLink(destination: ScreenC(didTapGoBack: {
showC = false
}), isActive: $showC) {
EmptyView()
}
}
}
}
struct ScreenC: View {
var didTapGoBack: () -> Void
var body: some View {
VStack {
Text("Screen C")
Button("Back to Screen B") {
didTapGoBack()
}
}
}
}
@main
struct TestNavApp: App {
var body: some Scene {
WindowGroup {
ScreenA()
}
}
}
2
Answers
In addition to @La pieuvre answer, to make this handling even easier on iOS 14 (like the handling for iOS 15 +). We can create an extension for EnvironmentValues
Then we can use it in a more cleaner way, like in iOS 15+
So we can get rid of calling
presentationMode.wrappedValue.dismiss()
all the timeThere is a better way to do that and it has the advantage to work 🙂
you can use the @environment(.dismiss) property and call it to dismiss your current view. It makes your code simpler as well. Here is the result :
Note that NavigationLink(destination:isActive:) is deprecated.
Here is the version with the updated code :
[Edit] for iOS 14 support we need to use
@Environment(.presentationMode) var presentationMode
as you pointed out in your commentHere is the iOS 14 version of the code :