Панель навигации не анимируется во время пользовательского перехода с помощью `popToRootViewController` в стековой навигации UINavigationController - PullRequest
0 голосов
/ 04 мая 2019

Использование Swift-5.0.1, Xcode-10.2.1, iOS-12.2,

У меня наблюдается очень странная проблема (которая заняла слишком много времени):

Мой стек навигации с UINavigationController работает хорошо.Я могу нажать и выскочить из одного ViewController в другой.В моем случае я использую шаблон Координатора с Маршрутизатором (но это не важно для этой проблемы здесь, я предполагаю).

Я использую два метода на моем UINavigationController, чтобы выскочить назад в моем стеке навигации

  1. popViewController
  2. popToRootViewController

Идея состоит в том, чтобы использовать popViewController для возврата одного ViewController в стек.И использовать popToRootViewController, чтобы вернуться обратно к первому ViewController в стеке.Пока все хорошо!

Но теперь проблема:

Если я использую собственные переходы анимации для переходов popBack-navigation, все будет запутано!

Точнее, панель навигации, использующая popToRootViewController с пользовательским переходом, полностью испорчена и не выполняет анимацию должным образом !!!!

С "не правильно" я имею в виду:Панель навигации выскакивает мгновенно, а не анимируется.

При использовании popViewController все работает, и панель навигации делает переход плавным и приятным, как и ожидалось.

Почему разница между popViewController и popToRootViewController с точки зрения анимации навигационной панели ???

Я знаю, что мог бы также использовать Segue для пользовательских анимаций.Но я не хочу использовать Segue, поскольку он предотвращает расцепление кода и, следовательно, тестирование.Я действительно хотел бы сохранить свой координатор и маршрутизатор и анимировать переходы с помощью UINavigationController-Delegate.

Вот видео, которое показывает разницу:

-> содержимое экрановне имеет значения.Просматривайте заголовки, чтобы увидеть, какой номер страницы и наблюдайте анимацию панели навигации.

-> пожалуйста, обратите внимание на панель навигации и обратите внимание на разницу между переходом со страницы 3 на 2 по сравнению сстраница 3-к-1.

-> Вы можете четко заметить, как панель навигации для перехода со страницы 3-в-1 происходит мгновенно, а остальная часть страницы 1 постепенно затухает, как и ожидалось (как и не должно быть - NavBarслишком быстро !!!)

-> Для перехода со страницы 3 на 2 все оживляет, включая панель навигации вместе со всей остальной страницей (как и должно быть !!)

enter image description here

Вот мой код:

вызов popViewController:

let t = CustomFadeTransition(withDuration: 1.0)
self.router.popModule(transition: t, animated: true)

вызов popToRootViewController:

let t = CustomFadeTransition(withDuration: 1.0)
self.router.popToRootModuleWithTransition(transition: t, animated: true)

Реализация Router с методами делегата перехода (выдержки ..)

final class Router: NSObject, RouterProtocol {

    private weak var rootController: UINavigationController?
    private var completions: [UIViewController : () -> Void]
    private var transition: UIViewControllerAnimatedTransitioning?

    // ...

    func popModule(transition: UIViewControllerAnimatedTransitioning?, animated: Bool) {
        self.transition = transition
        let _ = rootController?.popViewController(animated: animated)
    }

    func popToRootModuleWithTransition(transition: UIViewControllerAnimatedTransitioning?, animated: Bool) {
        self.transition = transition
        let _ = self.rootController?.popToRootViewController(animated: animated) 
    }

}

extension Router: UINavigationControllerDelegate, UIViewControllerTransitioningDelegate {

    func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return self.transition
    }

    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return self.transition
    }
}

.

Реализация CustomFadeTransition (здесь не важно, так как любой переход показывает запутанныйвверх Navigation-Bar ... но чтобы быть полным здесь код ..)

class CustomFadeTransition: NSObject, UIViewControllerAnimatedTransitioning {
    let duration: TimeInterval
    let presenting: Bool

    init(withDuration: TimeInterval = 0.2, presenting: Bool = true) {
        self.duration = withDuration
        self.presenting = presenting
        super.init()
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        let from   = transitionContext.viewController(forKey: .from)!
        let to     = transitionContext.viewController(forKey: .to)!
        let container = transitionContext.containerView
        if presenting {
            container.addSubview(to.view)
            to.view.alpha = 0.0
        } else {
            container.insertSubview(to.view, belowSubview: from.view)
        }
        UIView.animate(withDuration: (duration * 2), animations: {
            if self.presenting {
                to.view.alpha = 1.0
            } else {
                from.view.alpha = 0.0
            }
        }, completion: { value in
            let success = !transitionContext.transitionWasCancelled
            if !success {
                to.view.removeFromSuperview()
            }
            transitionContext.completeTransition(success)
        })
    }

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return duration
    }
}
...