How to get a UIViewController from a SwiftUI View in a UIKit Navigation Controller

257 Views Asked by At

In my SwiftUI/UIKit project, we're using UIKit's Navigation Controller for navigation. Currently, I have a function that gets a UIViewController from a SwiftUI View:

func popTo<T: View>(viewType: T.Type, animated: Bool) {
    if let viewController = rootNavigationController.viewControllers.first(where: {
        $0.self.description.contains(String(describing: viewType))
    }) {
        self.rootNavigationController.popToViewController(viewController, animated: animated)
    }
}

I want to make this more robust without relying on strings. I'd like to directly filter by the type. Here's an example:

if let firstHostingController = rootNavigationController.viewControllers.first(where: { $0 is UIHostingController<MyView> }){
    self.popToView(viewController: firstHostingController, animated: true)
}

Given that we're working within a UIKit Navigation Controller, how can I modify my popTo function for this without using strings for type comparison?

1

There are 1 best solutions below

4
Sweeper On

Your second code snippet is almost there. Just replace MyView with the type parameter T.

extension UINavigationController {
    func popTo<T: View>(viewType: T.Type, animated: Bool) {
        if let firstHostingController = viewControllers.first(where: { $0 is UIHostingController<T> }){
            self.popToViewController(firstHostingController, animated: true)
        }
    }
}