swiftuiios16xcode14swiftui-navigationstack

Why doesn't clearing the new iOS 16 SwiftUI NavigationPath to "pop to root" animate smoothly back to the root view?


I have a new iOS 16 SwiftUI NavigationStack with navigation determined by the NavigationDestination modifier which works fine.

My question is why doesn't it animate smoothly by sliding back to the root view when clearing the NavigationPath if you are more than one view deep within the stack?

It works if you are only one level deep, but anything lower than that causes "popping to root" to just jump back to the root view without the sliding animation.

Is this a "feature" or bug or am I doing something incorrectly?

Steps to re-create the issue

Demo of Issue

enter image description here

Demo Code (using Xcode 14.0 and iOS 16.0):

import SwiftUI
struct DemoPop: View {

    @State private var path = NavigationPath()
    
    var body: some View {
        
        VStack {
            
            NavigationStack(path: $path) {
                   
                List {
                    Section("List One") {
                        NavigationLink("Navigate to View 1", value: "View 1")
                        NavigationLink("Navigate to View 2", value: "View 2")
                    }
                }
                .navigationDestination(for: String.self) { textDesc in
                    
                    VStack {
                        Text(textDesc).padding()
                        Button("Navigate to View 3") {
                            path.append("View 3")
                        }.padding()
                        
                        Button("Pop to Root View") {
                            path.removeLast(path.count)
                        }.padding()
                    }
                }
                .navigationTitle("Test Pop To Root")
            }
        }
    }
}
    

struct DemoPop_Previews: PreviewProvider {
    static var previews: some View {
        DemoPop()
    }
}

Update 1:

Think the code above is correct so possibly a bug as mentioned in comments as I have just seen a YouTube video that exhibits the same behaviour - Youtube tutorial - around time line 19:25 - you will see pop to root just jumps back to start.

Update 2:

This has been fixed in iOS 16.2


Solution

  • This has been fixed by Apple on iOS 16.2

    For iOS 16.0 and 16.1 here's a 100% working, one-liner solution. Add this SPM library to your codebase https://github.com/davdroman/swiftui-navigation-transitions (version 0.7.1 or later) and simply:

    import NavigationTransitions
    import SwiftUI
    
    struct DemoPop: View {
    
        @State private var path = NavigationPath()
    
        var body: some View {
            NavigationStack(path: $path) {
                List {
                    Section("List One") {
                        NavigationLink("Navigate to View 1", value: "View 1")
                        NavigationLink("Navigate to View 2", value: "View 2")
                    }
                }
                .navigationDestination(for: String.self) { textDesc in
    
                    VStack {
                        Text(textDesc).padding()
                        Button("Navigate to View 3") {
                            path.append("View 3")
                        }.padding()
    
                        Button("Pop to Root View") {
                            path.removeLast(path.count)
                        }.padding()
                    }
                }
                .navigationTitle("Test Pop To Root")
            }
            .navigationTransition(.default) // one-liner ✨
        }
    }
    
    
    struct DemoPop_Previews: PreviewProvider {
        static var previews: some View {
            DemoPop()
        }
    }