A lightweight library based on the Coordinator pattern and is a compact version from XCoordinator.
Coordinator is creating reduce burden of navigations for UIViewController that allow groups a particular flow to visualize the transition between views.
Create a Route which defines all navigation paths for a particular flow, and preparation of transition based on route being triggered in your Coordinator.
In following example, I create the HomeRoute
enum describes which routes can be triggered.
enum HomeRoute: Route {
case home
case detail
case back
}
class HomeCoordinator: NavigationCoordinator<HomeRoute> {
init(rootViewController: UINavigationController) {
super.init(rootViewController: rootViewController, initialRoute: .home)
}
override func performTransition(for route: HomeRoute) {
switch route {
case .home:
let homeVC = HomeViewController()
homeVC.viewModel = HomeViewModel(router: strongRouter)
transitionPerformer.push(homeVC)
case .detail:
let homeVC = DetailViewController()
homeVC.viewModel = DetailViewModel(router: strongRouter)
transitionPerformer.push(homeVC)
case .back:
transitionPerformer.pop()
}
}
}
Routes are only allowed triggers within Coordinators and ViewModels. In following example, It describes how to trigger routes in ViewModel:
class HomeViewModel {
let router: StrongRouter<HomeRoute>
init(router: StrongRouter<HomeRoute>) {
self.router = router
}
func toDetail() {
router.trigger(.detail)
}
}
A custom Coordinator can be used BaseCoordinator
as superclass for custom implementtation.
open class NavigationCoordinator<RouteType: Route>: BaseCoordinator<RouteType, NavigationTransition> {
public init(rootViewController: RootViewController = RootViewController(), isNavigationBarHidden: Bool = false, initialRoute: RouteType...) {
super.init(rootViewController: rootViewController, initialRoute: initialRoute)
rootViewController.isNavigationBarHidden = isNavigationBarHidden
}
}
Create a transition using Transition
for default implementation which define transitions based on type of RootViewController
.
For example, the UINavigationController
can have push
, pop
, setRoot
, popToRoot
.But UIViewController
have only present
, dismiss
transition. Also you can following RootTransition
for own custom transition.
public typealias NavigationTransition = Transition<UINavigationController>
public extension Transition where RootViewController == UINavigationController {
func push(_ presentable: Presentable, animated: Bool = true, hidesBottomBarWhenPushed: Bool = false) {
let viewController = presentable.viewController
guard viewController is UINavigationController == false else {
return
}
viewController.hidesBottomBarWhenPushed = hidesBottomBarWhenPushed
rootViewController.pushViewController(viewController, animated: animated)
}
func pop(animated: Bool = true) {
rootViewController.popViewController(animated: animated)
}
func popToRoot(animated: Bool = true) {
rootViewController.popToRootViewController(animated: animated)
}
func setRoot(_ presentable: Presentable, animated: Bool = true) {
let viewController = presentable.viewController
guard viewController != rootViewController else {
return
}
rootViewController.setViewControllers([viewController], animated: animated)
}
func setRoot(_ presentables: [Presentable], animated: Bool = true) {
let viewControllers = presentables.map({ $0.viewController })
guard !viewControllers.contains(rootViewController) else {
return
}
rootViewController.setViewControllers(viewControllers, animated: animated)
}
}
ModernCoordinator is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod 'ModernCoordinator'
ModernCoordinator is available through Carthage. To install it, add this to your Cartfile:
github "phamdinhduc795397/ModernCoordinator"
Swift Package Manager is supported.
Duc Pham, [email protected]
Coordinator is available under the MIT license. See the LICENSE file for more info.