4

For some reason, clearing a navigation stack gives an unintended animation when compared to dismissing regularly. It clears the screen before it actually animates away. How can you pop back to root normally without the clearing of the screen?

https://imgur.com/a/GYhtmCK

struct ContentView: View {
    @State var navigationPath: NavigationPath = NavigationPath()
    
    var body: some View {
        NavigationStack(path: $navigationPath) {
            ZStack {
                Color.red
                NavigationLink(value: 0) {
                    Text("test")
                }
            }
            .navigationDestination(for: Int.self) { _ in
                SubView(navigationPath: $navigationPath)
            }
        }
    }
}

struct SubView: View {
    @Binding var navigationPath: NavigationPath
    
    var body: some View {
        ZStack {
            Color.green
            Button {
                navigationPath = NavigationPath()
            } label: {
                Text("back")
            }

        }
    }
}
6
  • I don't see this when running on an iPhone 14 Pro simulator with iOS 16.4. The green page slides off seamlessly as the red page slides back in. Pressing the Back link (top-left) works just as well as pressing the Button on the green page. What environment are you using?
    – Benzy Neez
    Sep 7, 2023 at 10:11
  • @BenzyNeez I am seeing the issue. iPhone 14 Pro on iOS 17 latest beta. Sep 7, 2023 at 20:28
  • This looks like a bug for swiftui not from you. My guess is state from parent view is handled before checking animation of current view. I would suggest to not use @Binding for navigation path, like putting it inside environment object.
    – andylee
    Sep 11, 2023 at 8:18
  • I encountered the same problem, but in my case it only happened on simulator. Could you try on a real device if it still occurs?
    – Martin
    Nov 27, 2023 at 15:47
  • 1
    @Martin Actually, I just rebuilt the app again on my phone and the animation works correctly. It looks like the bug was fixed recently!
    – fballjeff
    Nov 28, 2023 at 23:18

2 Answers 2

0

How can you pop back to root normally without the clearing of the screen? You could try this alternative approach, using dismiss() to go back, works for me.

struct ContentView: View {
    @State var navigationPath: NavigationPath = NavigationPath()
    
    var body: some View {
        NavigationStack(path: $navigationPath) {
            ZStack {
                Color.red
                NavigationLink(value: 0) {
                    Text("test")
                }
            }
            .navigationDestination(for: Int.self) { val in
                SubView() // <-- here
            }
        }
    }
}

struct SubView: View {
    @Environment(\.dismiss) var dismiss  // <-- here
    
    var body: some View {
        ZStack {
            Color.green
            Button {
                dismiss() // <-- here
            } label: {
                Text("back")
            }
        }
    }
}
2
  • This works if you only intend to dismiss the SubView from inside the view itself. I think the question more aims to have a programmatic way to dismiss the view with only a reference to the navigation path. This would be useful, for example, if we have a tab bar and we want to navigate back to the root tab when a tab bar button is pressed. Sep 14, 2023 at 6:11
  • I've only answered the question as posted, I did not speculate or second guessed what the OP wanted. The OP should make it clear if the question is ...to have a programmatic way to dismiss the view with only a reference to the navigation path Sep 14, 2023 at 6:26
0

Animation seems to be working properly now, looks like SwifUI has patched the bug.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.