无法删除子协调器,因为transitionCoordinator在navigationController委托方法中为nil

问题描述 投票:1回答:1

简述:

我已经实现了Soroush's Coordinators体系结构。一切正常,除了删除先前(子)协调器所需的删除部分。

场景:

我有两个ViewController,分别命名为HomeViewControllerMyGroupsViewController。每个都有自己的协调器,分别命名为HomeCoordinatorMyGroupsCoordinator

用户点击HomeViewController上的按钮,该按钮触发gotoMyGroupsTapped功能并使用户进入MyGroupsViewController,然后用户点击MyGroupsViewController上的另一个按钮,通过触发HomeViewController使用户回到gotoHomePage()

非常简单! :HomeVC-> MyGroupsVC-> HomeVC

但是问题是:

在两个协调器中,

navigationController.transitionCoordinator?func navigationController(..., didShow viewController: UIViewController...)中为nil,并且我无法在每个转换中都删除子协调器。

在两个协调器的navigationController.delegate = self函数中设置start()是否正确?

我应该在navigationController?.popViewController(animated: false )函数中使用backToHomePage()吗?因为Paul Hudson仅使用了pushViewController

我的代码[简化版本]:

HomeCoordinator.swift

import Foundation
import UIKit

class HomeCoordinator: NSObject,Coordinator,UINavigationControllerDelegate {
    var childCoordinators = [Coordinator]()
    var navigationController: UINavigationController
    weak var parentCoordinator : Coordinator?
    init(navigationController: UINavigationController) {
        self.navigationController = navigationController
    }

     func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
         // Transition here is nil
         print(" Transition : ",navigationController.transitionCoordinator)
         guard let fromViewController = navigationController.transitionCoordinator?.viewController(forKey: .from) else {
             print("Unknown fromViewController!")
             return
         }
         // Removing a child coordinator
     }

    func gotoMyGroups (){
         let groupsCoordinator = GroupsCoordinator(navigationController: navigationController)
         childCoordinators.append(groupsCoordinator)
         groupsCoordinator.parentCoordinator = self
         groupsCoordinator.start()
      }

     func start() {
        let vc = HomeViewController.instantiate()
        vc.coordinator = self
        navigationController.delegate = self
        navigationController.pushViewController(vc, animated: false)
        navigationController.setNavigationBarHidden(true, animated: false)
     }
}

MyGroupsCoordinator.swift

import Foundation
import UIKit

class MyGroupsCoordinator: NSObject,Coordinator,UINavigationControllerDelegate {
    var childCoordinators = [Coordinator]()
    var navigationController: UINavigationController
    weak var parentCoordinator : Coordinator?
    init(navigationController: UINavigationController) {
        self.navigationController = navigationController
    }

     func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
         // Transition here is nil
         print(" Transition : ",navigationController.transitionCoordinator)
         guard let fromViewController = navigationController.transitionCoordinator?.viewController(forKey: .from) else {
             print("Unknown fromViewController!")
             return
         }
         // Removing a child coordinator
     }

     func start() {
        let vc = MyGroupViewController.instantiate()
        vc.coordinator = self
        navigationController.delegate = self
        navigationController.pushViewController(vc, animated: false)
        navigationController.setNavigationBarHidden(true, animated: false)
     }
}

MyGroupViewController.magik

class MyGroupViewController :  UIViewControllerWithCoordinator,UITextFieldDelegate,Storyboarded{

     @IBAction func gotoHomePage(_ sender: Any) {
         if let coord = coordinator as? GroupsCoordinator {
             coord.parentCoordinator?.start()
         }
     }
 }

HomeViewController.swift

 class HomeViewController: UIViewControllerWithCoordinator,Storyboarded {
     @IBAction func gotoMyGroupsTapped(_ sender: Any) {
         guard let acoordinator = coordinator as? HomeCoordinator else {
             return
         }
         acoordinator.gotoMyGroups()
     }
swift uinavigationcontroller coordinator-pattern transition-coordinator
1个回答
0
投票

在我看来,这里对协调器模式的使用感到困惑。

[从您的预期流HomeVC -> MyGroupsVC -> HomeVC,如果您的意思是level1 -> level2 -> level3,则GroupsCoordinator应该使用自己的新HomeCoordinator创建一个新HomeVC实例。

所以不是您以前的代码

class MyGroupViewController ... {
    @IBAction func gotoHomePage(_ sender: Any) {
        if let coord = coordinator as? GroupsCoordinator {
            coord.parentCoordinator?.start()
        }
    }
}

我将其更改为

class MyGroupViewController ... {
    @IBAction func gotoHomePage(_ sender: Any) {
        if let coord = coordinator as? GroupsCoordinator {
            coord.goToHome()
        }
    }
}

class MyGroupsCoordinator ... {

    func goToHome() {
        let homeCoordinator = HomeCoordinator(navigationController: navigationController)
        childCoordinators.append(homeCoordinator)
        groupsCoordinator.parentCoordinator = self
        groupsCoordinator.start()
    }
}

这将使您可以在HomeVC -> MyGroupsVC -> HomeVC中创建一个全新的页面。


但是],如果您是用这种方法level1 -> level2 -> (back) level1表示的,则您需要终止MyGroupsCoordinator并在导航时从父级中删除。

您已经注意到,为此,您需要使用UINavigationControllerDelegate以便在用户向后导航(弹出代码或带有经典的后退按钮)时得到通知。

我发现的一个解决方案是,当从中删除Router时,使用UIViewController处理所有导航,还通过闭包通知要删除的右协调器。您可以阅读有关它的更多信息here

希望有帮助

© www.soinside.com 2019 - 2024. All rights reserved.