How to pop to root view via navigation stack in iOS 16

4k Views Asked by At

As we know Apple have introduced NavigationStack in SwiftUI available from iOS16.*

Let say I have created ViewA, ViewB, ViewC, ViewD And now I have navigated like ViewA->ViewB->ViewC->ViewD
Now I am looking to pop to root view i.e on ViewA from ViewD

Any help would be appreciated.

2

There are 2 best solutions below

0
On

if you are using swift ui (with iOS 16 or greater), I would suggest to use

// fill path with your navigation items as soon as you want to add a new path
@State var path: [Item] = []

// once done, you can manipulate this array of path as you need 
// for example, if you want to popToRootController, you will do the following

var body: some View {

    NavigationStack(path: $path) {
        List(Items) { item in 
            // creates a navigation link
            NavigationLink(item.name, value: item)
        }
    }
    // this represents the destination for each link in the list
    .navigationDestination(for: Item.self) { item in
        VStack {
            // Some View
            // Add some action or event to empty path
            // this is just an example
            Button("PopToRoot") {

                // what is similar to popToRootViewController
                // in iOS 16 or above you just do
                path = []
            }
        }
   }
}

// NOTE:
path = [] // this is exactly similar to popToRootViewController

1
On

This worked for me but I can't find the url so I will just share the code. You can also try it out...

Create a file and add the following;

import Foundation

struct NavigationUtil {
    static func popToRootView() {
        DispatchQueue.main.asyncAfter(deadline: .now()) {
            findNavigationController(viewController: 
UIApplication.shared.windows.filter { $0.isKeyWindow 
}.first?.rootViewController)?
                .popToRootViewController(animated: true)
        }
    }
static func findNavigationController(viewController: UIViewController?) 
-> UINavigationController? {
        guard let viewController = viewController else {
            return nil
        }
if let navigationController = viewController as? UINavigationController 
{
        return navigationController
    }
for childViewController in viewController.children {
        return findNavigationController(viewController: 
childViewController)
    }
return nil
    }
}

Then call this from anywhere in your code;

NavigationUtil.popToRootView()