iOS Development

ios – Coordinator sample in SwiftUI with out UINavigationController?

Spread the love


Going off of this text about utilizing coordinator sample in SwiftUI, it feels unnatural to depend on UIKit’s UINavigationController to do the push/pop/current.

Related code:

import SwiftUI

open class Coordinator<Router: NavigationRouter>: ObservableObject {
    
    public let navigationController: UINavigationController
    public let startingRoute: Router?
    
    public init(navigationController: UINavigationController = .init(), startingRoute: Router? = nil) {
        self.navigationController = navigationController
        self.startingRoute = startingRoute
    }
    
    public func begin() {
        guard let route = startingRoute else { return }
        present(route)
    }
    
    public func present(_ route: Router, animated: Bool = true) {
        let view = route.view()
        let viewWithCoordinator = view.environmentObject(self)
        let viewController = UIHostingController(rootView: viewWithCoordinator)
        change route.transition {
        case .push:
            navigationController.pushViewController(viewController, animated: animated)
        case .presentModally:
            viewController.modalPresentationStyle = .formSheet
            navigationController.current(viewController, animated: animated)
        case .presentFullscreen:
            viewController.modalPresentationStyle = .fullScreen
            navigationController.current(viewController, animated: animated)
        }
    }
    
    public func pop(animated: Bool = true) {
        navigationController.popViewController(animated: animated)
    }
    
    public func popToRoot(animated: Bool = true) {
        navigationController.popToRootViewController(animated: animated)
    }
    
    open func dismiss(animated: Bool = true) {
        navigationController.dismiss(animated: true) { [weak self] in
            /// as a result of there's a leak in UIHostingControllers that stops from deallocation
            self?.navigationController.viewControllers = []
        }
    }
}

struct MapView: View {
    
    @EnvironmentObject var coordinator: Coordinator<MapRouter>
    var physique: some View {
        NavigationView {
            Button("Go to town") {
                coordinator.present(.metropolis(named: "El Paso"))
            }
        }
    }
}

I am conscious I can do it utilizing NavigationPath however I have to help OS < 16 so that’s not an choice. Is it potential to do the push/pop/current utilizing NavigationView & NavigationLink solely?

Leave a Reply

Your email address will not be published. Required fields are marked *