Я пытаюсь узнать, как работает шаблон координатора, хотя у меня возникли некоторые проблемы с делегатами от одного дочернего контроллера представления координатора к другому.
Например, у меня есть домашний видеомагнитофон, и я хочу перейти к деталям с помощью одной кнопки, но я бы хотел, чтобы это управлялось из HomeTabBarCoordinator с помощью следующего кода.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
window = UIWindow()
let tabBarController = UITabBarController()
window?.rootViewController = tabBarController
let about = HomeTabBarCoordinator()
let one = deGenericize(about)
let appCoordinator = TabAppCoordinator(tabBarController: tabBarController, tabs: [one])
appCoordinator.start()
window?.makeKeyAndVisible()
return true
}
public protocol TabCoordinator {
associatedtype RootType: UIViewController
var rootController: RootType { get }
var tabBarItem: UITabBarItem { get }
}
public class AnyTabCoordinator {
var rootController: UIViewController
var tabBarItem: UITabBarItem
public init<T: TabCoordinator>(_ tabCoordinator: T) {
rootController = tabCoordinator.rootController
tabBarItem = tabCoordinator.tabBarItem
}
}
public func deGenericize<T: TabCoordinator>(_ coordinator: T) -> AnyTabCoordinator {
return AnyTabCoordinator(coordinator)
}
public class TabAppCoordinator {
var tabBarController: UITabBarController
var tabs: [AnyTabCoordinator]
public init(tabBarController: UITabBarController, tabs: [AnyTabCoordinator]) {
self.tabBarController = tabBarController
self.tabs = tabs
}
public func start() {
tabBarController.viewControllers = tabs.map { (coordinator) -> UIViewController in
return coordinator.rootController
}
}
}
protocol HomeTabBarDelegate: class {
func goToProfile()
}
class HomeTabBarCoordinator: NSObject, TabCoordinator {
var rootController: UINavigationController
var tabBarItem: UITabBarItem = UITabBarItem(title: "About", image: UIImage(named: "AboutTabBarIcon"), selectedImage: UIImage(named: "AboutTabBarIcon_Filled"))
let homeVC: HomeViewController
override init() {
self.homeVC = HomeViewController()
self.rootController = UINavigationController()
super.init()
rootController.viewControllers = [homeVC]
rootController.tabBarItem = tabBarItem
homeVC.delegate = self //is being set properly when i add a breakpoint here
}
}
extension HomeTabBarCoordinator: HomeTabBarDelegate {
func goToProfile() { //never being executed
let details = DetailsViewController()
rootController.pushViewController(details, animated: true)
}
}
class HomeViewController: UIViewController {
weak var delegate: HomeTabBarDelegate?
let button = UIButton()
init() {
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupView() {
view.addSubview(button)
button.snp.makeConstraints { (make) in
make.center.equalToSuperview()
}
view.backgroundColor = .white
button.setTitle("test", for: .normal)
button.setTitleColor(.red, for: .normal)
button.addTarget(self, action: #selector(didPress), for: .touchDown)
}
@objc func didPress() {
delegate?.goToProfile() //delegate is nil
}
override func viewDidLoad() {
super.viewDidLoad()
setupView()
// Do any additional setup after loading the view.
}
}
Я не знаю, что происходит, и он продолжает давать мне нулевой делегат в HomeViewController (см. Комментарии в коде).
Есть идеи?
ОБНОВЛЕНИЕ
, как @purpose упомянул об отмене HomeTabBarCoordinator
из didFinishLaunchingWithOptions
, я изменил функцию appDelegate на следующую, но все еще имеет ту же проблему. Как я могу сохранить сильный реф. до let about = HomeTabBarCoordinator()
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var appCoordinator: TabAppCoordinator?
let tabBarController = UITabBarController()
let about = HomeTabBarCoordinator()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let one = deGenericize(about)
appCoordinator = TabAppCoordinator(tabBarController: tabBarController, tabs: [one])
appCoordinator?.start()
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = tabBarController
window?.makeKeyAndVisible()
return true
}