Методы UINavigationControllerDelegate не вызываются - PullRequest
0 голосов
/ 10 июля 2019

Я пытаюсь сделать пользовательские переходы при нажатии / выталкивании viewControllers из пользовательского класса UINavigationController. Я реализую метод 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 в моей иерархии навигации делегировать push или всплывающие окна для этого CustomNavigationController выше. Например, это корневой vc, назначенный контроллеру навигации. Так как он лежит как корень, ему никогда не нужно выдвигать себя или быть вытолкнутым, как это представлено при представлении CustomNavigationController. Он делегирует CustomNavigationController, когда обнаруживает, что поверх него должен быть представлен другой VC:

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 должен вызываться всякий раз, когда выполняется push или pop, поскольку я устанавливаю переменную delegate в self в инициализаторе?

1 Ответ

1 голос
/ 10 июля 2019

Ваш контроллер навигации должен иметь контроллер корневого представления.И тогда вы должны выдвинуть пользовательский контроллер представления из вашего корневого контроллера представления.И вызов метода делегата

Код контроллера навигации: импорт 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)
    }

}

Установка корневого контроллера представления в качестве корневого для контроллера навигации в раскадровке

...