Странная анимация панели навигации при переходе на дочерний UINavigationController - PullRequest
0 голосов
/ 25 января 2019

Я создал небольшой проект, чтобы повторить эту проблему.

Это единственный файл ...

Краткий код

class RootViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .red
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        showBlue()
    }

    @objc func showBlue() {
        let vc = UIViewController()
        vc.view.backgroundColor = .blue

        let nvc = UINavigationController(rootViewController: vc)

        vc.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(showGreen))

        transition(to: nvc)
    }

    @objc func showGreen() {
        let vc = UIViewController()
        vc.view.backgroundColor = .green

        let nvc = UINavigationController(rootViewController: vc)

        vc.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(showBlue))

        transition(to: nvc)
    }

    func transition(to toVC: UIViewController) {
        if let fromVC = children.first {
            transitionWithAnimation(fromVC: fromVC, toVC: toVC)
        } else {
            addWithoutAnimation(child: toVC)
        }
    }

    func addWithoutAnimation(child toVC: UIViewController) {
        addChild(toVC)
        view.addSubview(toVC.view)
        toVC.view.frame = view.bounds
        toVC.didMove(toParent: self)
    }

    func transitionWithAnimation(fromVC: UIViewController, toVC: UIViewController) {
        addChild(toVC)
        toVC.view.frame = view.bounds

        fromVC.willMove(toParent: nil)

        transition(
            from: fromVC,
            to: toVC,
            duration: 1.0,
            options: .transitionCrossDissolve,
            animations: nil) { _ in
                fromVC.removeFromParent()
                toVC.didMove(toParent: self)
        }
    }
}

Объясняя код

Сначала RootViewController выполняет showBlue. Это добавляет ребенка UINavigationController с rootViewController с синим фоном. Контроллер синего вида имеет кнопку Done, которая затем нацеливается на showGreen.

showGreen переходит на UINavigationController с зеленым фоном и кнопкой Done, предназначенной для showBlue.

Что я ожидал

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

Анимация задачи

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

enter image description here

Документация Apple об этом

Весь код точно соответствует документации Apple о добавлении дочерних контроллеров представления в пользовательский контроллер представления контейнера ... https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html

Вещи, которые я пытался

Я также пытался использовать ограничения AutoLayout вместо прямой установки рамки вида, но это ничего не изменило.

Я попытался запустить view.setNeedsLayout, а затем view.layoutIfNeeded() на новом контроллере вида view, но, похоже, это тоже не исправило его.

Нет странной анимации, если child не UINavigationController

Действительно странная вещь заключается в том, что если вы используете любой другой тип контроллера представления (кроме UINavigationController), то этого анимационного сбоя не произойдет. Например: если один из контроллеров представления является UITabBarController, то вкладки не имеют этой странной анимации. Даже странно, если вкладка содержит UINavigationController, то она также не имеет этой анимации. Это буквально просто, если прямой ребенок - UINavigationController.

Кто-нибудь испытывал это раньше? А вам удалось остановить странную анимацию?

1 Ответ

0 голосов
/ 25 января 2019

Если поместить код перехода в CATransation и использовать клавишу kCATransactionDisableActions для отключения неявных действий, это решит проблему:

    CATransaction.begin()
    CATransaction.setValue(kCFBooleanTrue, forKey:kCATransactionDisableActions)

    transition(
        from: fromVC,
        to: toVC,
        duration: 1.0,
        options: [.transitionCrossDissolve],
        animations: nil) { _ in
            fromVC.removeFromParent()
            toVC.didMove(toParent: self)
    }

    CATransaction.commit()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...