首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用子协调器检测返回导航

如何用子协调器检测返回导航
EN

Stack Overflow用户
提问于 2021-09-09 10:48:58
回答 1查看 121关注 0票数 1

我使用协调器模式和子协调器来提供松散耦合的代码,并且符合单一责任原则。为了处理向后导航,我决定使用导航控制器委托(相应地,本文使用https://www.hackingwithswift.com/articles/175/advanced-coordinator-pattern-tutorial-ios)。但我的问题是,我有家庭VC和家庭协调员,接下来我去锻炼VC与锻炼协调员,然后我去锻炼VC与锻炼协调员。

所以我想有一个锻炼协调员和锻炼协调员作为孩子的家庭协调员。

看起来一切正常,但是我的锻炼协调器和锻炼协调器之间有一个内存泄漏,因为我不能删除锻炼协调器后,我使用后退按钮导航。我的导航控制器委托不能识别我何时返回。

代码语言:javascript
复制
class HomeCoordinator: NSObject, Coordinator, UINavigationControllerDelegate {
    
    var childCoordinators = [Coordinator]()
    var navigationController: UINavigationController
    
    init(navigationController: UINavigationController) {
        self.navigationController = navigationController
        navigationController.navigationBar.prefersLargeTitles = true
        navigationController.navigationBar.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white]
    }

    func start() {
        navigationController.delegate = self
        let vc = HomeFactory.makeHomeScene(delegate: self)
        navigationController.pushViewController(vc, animated: false)
    }
    
    func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {

        guard let fromViewController = navigationController.transitionCoordinator?.viewController(forKey: .from) else { return }
        
        if navigationController.viewControllers.contains(fromViewController) {
            return
        }

        if let addWorkoutViewController = fromViewController as? NewWorkoutViewController {
            let workoutCoordinator = addWorkoutViewController.presenter?.workoutCoordinatorDelegate
            childDidFinish(workoutCoordinator)
        }
    }
}

extension HomeCoordinator: HomeCoordinatorDelegate {

    func goToWorkoutCreating() {
        let child = AddWorkoutCoordinator(navigationController: navigationController)
        child.passWorkoutToHomeDelegate = self
        childCoordinators.append(child)
        child.parentCoordinator = self
        child.start()
    }
}

class AddWorkoutCoordinator: NSObject, Coordinator, UINavigationControllerDelegate {
    
    var parentCoordinator: Coordinator?
    var exerciseNumber: Int?
    
    weak var passWorkoutToHomeDelegate: PassWorkoutToHome?

    var childCoordinators = [Coordinator]()
    var navigationController: UINavigationController
    
    init(navigationController: UINavigationController) {
        self.navigationController = navigationController
        navigationController.navigationBar.tintColor = .white
        
    }
    
    func start() {
        let vc = AddWorkoutFactory.makeAddWorkoutScene(delegate: self)
        navigationController.pushViewController(vc, animated: true)
    }
    
    func childDidFinish(_ child: Coordinator?) {
        for (index, coordinator) in childCoordinators.enumerated() {
            if coordinator === child {
                childCoordinators.remove(at: index)
                break
            }
        }
    }


       
// THIS FUNCTION IS NOT RESPOND AT ALL, BUT IT RESPONDS IN HOME COORDINATOR
        func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
    
        guard let fromViewController = navigationController.transitionCoordinator?.viewController(forKey: .from) else { return }


        if navigationController.viewControllers.contains(fromViewController) {
            return
        }
  
        if let newExerciseViewController = fromViewController as? NewExerciseViewController {
            
//            childDidFinish(newExerciseViewController.presenter?.exerciseCoordinatorDelegate)
//            childDidFinish(newExerciseViewController.presenter!.exerciseCoordinatorDelegate)
        }
    }
}

extension AddWorkoutCoordinator: AddWorkoutCoordinatorDelegate {
    
      func goToAddExercise() {
       
          let child = AddExerciseCoordinator(navigationController: navigationController)
          child.passExerciseToWorkoutDelegate = self
          childCoordinators.append(child)
          child.start()
      }





class AddExerciseCoordinator: NSObject, Coordinator {
    

    weak var passExerciseToWorkoutDelegate: PassExerciseToWorkoutDelegate?
    
    var childCoordinators = [Coordinator]()
    var navigationController: UINavigationController
    
    init(navigationController: UINavigationController) {
        self.navigationController = navigationController
        self.navigationController.navigationBar.tintColor = .white
    }
    
    func start() {
        let vc = AddExerciseFactory.makeAddExerciseScene(delegate: self)
        
        navigationController.pushViewController(vc, animated: true)
    }
    
    func startEditExercise(setData: [ExerciseFieldsModel], exerciseName: String) {
        let vc = AddExerciseFactory.makeAddExerciseScene(delegate: self)
        vc.presenter?.textFieldsModel = setData
        vc.exerciseText = exerciseName
        navigationController.pushViewController(vc, animated: true)
    }
}

extension AddExerciseCoordinator: NewExerciseCoordinatorDelegate {
    
    func saveExercise(newExercise: ExerciseCellInNewWorkout) {
        navigationController.popViewController(animated: true)
        passExerciseToWorkoutDelegate?.passExerciseToWorkout(exercise: newExercise)
    }
}

所以基本上的问题是,使用导航控制器委托didShow方法,我需要获取"fromViewController“的类型,所以如果我有一个像锻炼协调器这样的孩子,一切都好,我不能轻易地删除它,但当我有一个更深的层,所以我有锻炼协调器,在那之后,我不知道如何使用导航控制器委托didShow方法来识别是否弹出锻炼协调器。因此,我尝试在锻炼协调器中使用导航控制器didShow,但正如我在代码注释中所写的那样,它根本没有响应。

你能帮我得到一些关于如何检测用户是否在练习VC上点击后退按钮的建议吗?也许我的想法不好,只有锻炼协调者应该是孩子,而锻炼协调者不应该是。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-09 11:20:48

当您的ExerciseViewController超出作用域(被删除)时,它应该通知在导航控制器上推送它的对象。看起来那是你的ExerciseCoordinator。

按照设置UIKit的视图包含系统的方式设置您的协调器包含系统。其中协调器具有addChild(coordinator:)方法和removeFromParent()方法。当视图控制器通知协调器它超出了作用域时,协调器应该调用它的removeFromParent()方法。

上面的系统比依赖于didShow要好得多,并且适用于任何一种表示方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69116862

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档