2017-11-12 1 views
2

Meine App kann AppBaseController dynamisch ändern (Präsentiert nach dem Login). Es ist auf der folgenden sein kann:Generische Art der Rückgabe von: UIViewController, UINavigationController, UITabController

Menüsteuerung (Typ UIViewController), UINavigationController oder UITabBarController

ich diesen Controller mit einer Fabrik zu schaffen und würde die Fabrik zu einem Protokoll entsprechen wie das aussieht dies wie:

protocol MainRootApplication { 
    func create() -> UIViewController 
} 

2 Beispiele für Factory, die bestätigen: (Mit AutoInject Swinject für Dependency Injection)

class MenuControllerFactory: Factory,MainRootApplication { 
    func create() -> MenuController { 
     self.container.autoregister(MenuController.self, initializer: MenuController.init) 
     return self.container.resolve(MenuController.self)! 
    } 
} 

class MainTabBarControllerFactory: Factory, MainRootApplication { 
    func create() -> MainTabBarController { 
     self.container.autoregister(MainTabBarController.self, initializer: MainTabBarController.init) 
     return self.container.resolve(MainTabBarController.self)! 
    } 
} 

Wie Sie sehen, kann dies nicht erreicht werden, da "MainTabBarController" nicht vom Typ UIViewController ist.

Gibt es da eh nichts ohne Gewaltanwendung?

Antwort

1

Vielleicht einen zugeordneten Typ verwenden?

protocol MainRootApplication { 
    associatedtype ControllerType: UIViewController 
    func create() -> ControllerType 
} 

Und dann Ihre Fabriken aussehen wird:

class MenuControllerFactory: Factory,MainRootApplication { 
    typealias ControllerType = MenuController 
    func create() -> MenuController { 
     self.container.autoregister(MenuController.self, initializer: MenuController.init) 
     return self.container.resolve(MenuController.self)! 
    } 
} 

class MainTabBarControllerFactory: Factory, MainRootApplication { 
    typealias ControllerType = MainTabBarController 
    func create() -> MainTabBarController { 
     self.container.autoregister(MainTabBarController.self, initializer: MainTabBarController.init) 
     return self.container.resolve(MainTabBarController.self)! 
    } 
} 
+0

@Seeper wow Dank! Das ist so eine coole Art, es zu tun! Wird nur eine letzte Frage, wie ist das möglich? Das ist eigentlich Casting, aber ohne Casting, warum billigt der Compiler das? – MCMatan

+0

@MCMatan Schauen Sie sich schnell verwandte Typen an, um mehr darüber zu erfahren, wie sie funktionieren und warum sie besser sind als Protokolle mit generischen Typen. – Sweeper

Verwandte Themen