UINavigationControllerDelegate方法未调用

时间:2019-07-10 13:08:28

标签: ios swift animation uinavigationcontroller uikit

当从自定义UINavigationController类推入/弹出viewController时,我试图进行自定义转换。我正在实现UINavigationControllerDelegate方法 navigationController(_:animationControllerFor:from:to:),但不会被调用。

我正在情节提要中创建一个UINavigationController,并将其归类为CustomNavigationController。我还将在情节提要中为其分配根ViewController(我们将其称为根VC CustomViewControllerRoot)。

这是我正在使用的代码(经过简化且未经测试):


protocol NavigationDelegate {
 func pushCustomViewController()
 func popViewController()
}

class CustomNavigationController: UINavigationController, NavigationDelegate {

    init() {
      super.init(nibName: nil, bundle: nil)
      delegate = self
    }

    required init?(coder aDecoder: NSCoder) {
      super.init(coder: aDecoder)
    }

    override func viewDidLoad() {
      self.navigationBar.isHidden = true

      guard viewControllers.first is CustomViewControllerRoot else {fatalError("Error")}
      rootVC = viewControllers.first as? CustomViewControllerRoot
      rootVC?.navigationDelegate = self

      //Setup the rest of the viewControllers that are to be used
      customVC = CustomUIViewController()
      customVC?.navigationDelegate = self
    }

    var rootVC: CustomViewControllerRoot?
    var customVC: CustomViewController?    

    func pushCustomViewController() {
      if customVC != nil {
         self.pushViewController(customVC!, animated: true)
      }
    }

    func popViewController() {
      self.popViewController(animated: true)
    }
}


extension CustomNavigationController: UINavigationControllerDelegate {
    func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        // This is never called, even though the delegate is set in the initializer to CustomNavigationController
        print("TEST")
        return nil
    }

}

然后,我让导航层次结构中的每个自定义UIViewController子类委托推入或弹出到上面的CustomNavigationController。例如,这是分配给导航控制器的根vc。由于它作为根存在,因此它不需要像在显示CustomNavigationController时所显示的那样去推动或弹出。当发现另一个VC应该显示在它上面时,它将委托给CustomNavigationController

class CustomViewControllerRoot {

 var navigationDelegate: NavigationDelegate?

 override func viewDidLoad(){
   super.viewDidLoad()
 }

 @objc func someButtonPressedToPresentCustomVC(){
   navigationDelegate?.pushCustomViewController()
 }

}

解雇是在每个CustomViewController内部处理的,这也将弹出窗口委托给CustomNavigationController(我不想使用导航栏来解雇,因此从一开始就没有“后退按钮” ):

class CustomViewController: UIViewController {

 var navigationDelegate: NavigationDelegate?

 override func viewDidLoad(){
   super.viewDidLoad()
 }

 @objc func dismissViewController(){
   navigationDelegate?.popViewController()
 }  
}

据我了解,UINavigationControllerDelegate扩展名内的CustomNavigationController方法应在每次执行推入或弹出操作时调用,因为我将delegate变量设置为self在初始化程序中?

1 个答案:

答案 0 :(得分:1)

您的导航控制器应具有一个根视图控制器。 然后,您应该从根视图控制器中推送自定义视图控制器。和委托方法调用

导航控制器代码:导入UIKit

class CustomNV: UINavigationController {
    override func viewDidLoad() {
        super.viewDidLoad()
        delegate = self
    }
}

extension CustomNV: UINavigationControllerDelegate {
    func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        print("TEST")
        return nil
    }
}

RootViewController代码:

class RootViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        let viewController = UIViewController(nibName: nil, bundle: nil)
        viewController.view.backgroundColor = .green
        navigationController?.pushViewController(viewController, animated: true)
    }

}

将根视图控制器设置为情节提要中导航控制器的根