Я пытаюсь сделать пользовательские переходы при нажатии / выталкивании 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
в инициализаторе?