通过视图控制器的AppCoordinator委托

时间:2018-09-06 20:00:12

标签: swift swift3 swift4

尽管我在从一个儿童协调员的视图控制器到另一个儿童协调员的视图的委托方面遇到了一些问题,但我正在尝试了解协调器模式是如何工作的。 例如,我有一个家用vc,我想用一个按钮进入详细信息,但是我希望通过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所提到的,关于HomeTabBarCoordinatordidFinishLaunchingWithOptions脱位的情况下,我将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
    }

1 个答案:

答案 0 :(得分:0)

违规代码:

let about = HomeTabBarCoordinator()

它有什么作用?它创建一个局部变量,并将HomeTabBarCooordinator()对象存储在其中。
application(_:didFinishLaunchingWithOptions)结束后该怎么办?它会取消定义,因为没有创建新的强引用(声明了它的好代表!)。

您可能以为

public init<T: TabCoordinator>(_ tabCoordinator: T) {
    rootController = tabCoordinator.rootController
    tabBarItem = tabCoordinator.tabBarItem
}

将拯救您。让我们看看rootController还是tabBarItem是否强烈引用了我们的HomeTabBarCoordinator

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
    }
}

不,他们没有。再见HomeTabBarCoordinator!因此delegate变为零。

  

我如何保持强烈的评价。让= HomeTabBarCoordinator()

将其放在本身强烈引用的类中就足够了。任何没有被宣布为弱/无主的参考文献都是有力的,并且可以在封装类生存下来的情况下生存。

AppDelegate可以确保它不会自行取消初始化。