I have these protocols:
protocol Coordinator {
var rootViewController: UIViewController { get set }
func start()
}
protocol UIViewControllerFactory {
func mainViewController() -> UIViewController
}
And I created a MainCoordinator that conforms to this protocol and I pass a factory that allows me to decouple the coordinator from creating and capturing a concrete type so it can be polymorphic and can be used with more implementations of UIViewController either as rootViewControllers and mainMenuViewController as shown below:
class MainCoordinator: Coordinator {
var rootViewController: UIViewController
let factory: UIViewControllerFactory
init(rootViewController: UIViewController, factory: UIViewControllerFactory) {
self.rootViewController = rootViewController
}
start() {
guard let mainVC = factory.mainViewController() as? MainViewController, let rootViewController = rootViewController as? UINavigationViewController else { return }
mainVC.delegate = self
rootViewController.push(mainVC, animated: true)
}
As you can see, although I've created the coordinator to accept any subclass of UIViewController it has been coupled in the start function to the concrete implementation of UIViewController: MainViewController.
So my question is how to decouple it from MainViewController and have it more polymorphic ?
You can pass coordinator as a parameter type in factory function and set delegate
directly in factory function while creating controller instance. That way you wouldn't have to expose controller type
explicitly out of factory classes.
I came up with below approach.
protocol Coordinator {
var rootViewController: UIViewController { get set }
func start()
}
protocol UIViewControllerFactory {
func getViewController(delegateType:CoordinatoreTypes,delegateObject:Coordinator) -> UIViewController?
}
class MainCoordinator: Coordinator {
var rootViewController: UIViewController
let factory: UIViewControllerFactory
init(rootViewController: UIViewController, factory: UIViewControllerFactory) {
self.rootViewController = rootViewController
self.factory = factory
}
func start() {
guard let controller = factory.getViewController(delegateType: .MainCoordinator, delegateObject: self),let rootViewController = rootViewController as? UINavigationViewController else {
return
}
rootViewController.push(mainVC, animated: true)
}
}
extension MainCoordinator:DelegateCaller{
func printHello() {
print("helloo")
}
}
enum CoordinatoreTypes{
case MainCoordinator
case none
}
class Factory:UIViewControllerFactory{
func getViewController(delegateType:CoordinatoreTypes,delegateObject:Coordinator) -> UIViewController?{
switch delegateType{
case .MainCoordinator:
let controller = MainViewController()
controller.delegate = delegateObject as? MainCoordinator
return controller
case .none:
break
}
return nil
}
}
class MainViewController:UIViewController{
weak var delegate:DelegateCaller?
}
protocol DelegateCaller:AnyObject{
func printHello()
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.