Route
Router doesn't hold any state, all values required for navigation are calculated on the fly based on UIViewController
properties. It's fully compatible with existing project navigation system. You can easily mix router navigation command calls with performing segues or push/present/dismiss/etc. Therefore it can be painlesly added to any ongoing project.
Features
- Simple navigation commands
- Navigate back to any controller with result
- Jump to any controller in navigation tree
- Super friendly to existing project navigation
- Can be painlessly added to ongoing project
- Architecture agnostic
- Lightweight
Add
Provide access point to router (from view controller, for example):
extension UIViewController {
var router: Router {
return Router(window: UIApplication.shared.keyWindow, controller: self)
}
}
Example
Usage
Forward Navigation
Present controller
let controller: UIViewController = ...
router.present(controller, animated: true, completion: { ... })
Push controller in current navigation controller
router.push(controller, animated: true, completion: { ... })
Note: completion closure is called immediately after the transition is completed.
Backward Navigation
Back to arbitrary controller
router.back(
to: ViewController.self,
animated: true,
condition: { $0.id == 3 },
prepare: { controller in ... },
completion: { controller in ... }
)
Provide condition in addition to target controller type, in case more than one controller of such type in back stack.
Back to previous controller
router.back(
animated: true,
prepare: { controller in ... },
completion: { controller in ... }
)
Back to window root
router.backToWindowRoot(
animated: true,
prepare: { controller in ... },
completion: { controller in ... }
)
Note: prepare closure is called before the transition begins. This closure can be used for returning some data to target controller.
Inplace Navigation
Replace current controller
router.replace(
with: controller,
animated: true,
completion: { ... }
)
Note: replace even window root view controller.
Set current window root view controller
router.setWindowRoot(
controller,
animated: true,
completion: { ... }
)
Jump to controller
Go to view controller wherever it positioned in navigation tree.
router.jump(
to: ViewController.self,
animated: true,
condition: { $0.id == 3 },
prepare: { controller in ... },
completion: { controller in ... }
)
Navigation Tree Info
Find controller
let controller = router.find(ViewController.self, condition: { $0.id == 3 })
Top view controller
let controller = router.topController
Back stack
Get back navigation stack from current controller to window root:
let controllers = router.backStack
Stack from root to top controller
let controllers = router.topStack
Custom container controllers
Custom container controller in navigation tree must adopt one of three container controller protocols.
Simple container
If container contains just one child controller it must implement ContainerController
protocol (example).
Stack container
If container contains stack of child controllers, like UINavigationController
, it must implement StackContainerController
protocol (example).
Flat container
If container contains child controller at one level, like UITabBarController
or UIPageViewController
, it must implement FlatContainerController
protocol. See tab bar example or page controller example.
Requirements
- Swift 4.2 +
- iOS 9.0 +
Istallation
Route doesn't contain any external dependencies.
CocoaPods
Add the following to Podfile
:
pod 'Route'
Manual
Download and drag files from Source folder into your Xcode project.
License
Route is distributed under the MIT License.