Я создал небольшой проект, чтобы повторить эту проблему.
Это единственный файл ...
Краткий код
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
.
Что я ожидал
Я ожидал (и хочу, чтобы это произошло), чтобы панель навигации перекрестно растворилась на месте без изменения размера.
Анимация задачи
Проблема в том, что во время анимированного перехода навигационная панель имеет странную анимацию. Что вы можете увидеть здесь ...
Документация Apple об этом
Весь код точно соответствует документации Apple о добавлении дочерних контроллеров представления в пользовательский контроллер представления контейнера ... https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html
Вещи, которые я пытался
Я также пытался использовать ограничения AutoLayout вместо прямой установки рамки вида, но это ничего не изменило.
Я попытался запустить view.setNeedsLayout
, а затем view.layoutIfNeeded()
на новом контроллере вида view
, но, похоже, это тоже не исправило его.
Нет странной анимации, если child не UINavigationController
Действительно странная вещь заключается в том, что если вы используете любой другой тип контроллера представления (кроме UINavigationController
), то этого анимационного сбоя не произойдет. Например: если один из контроллеров представления является UITabBarController
, то вкладки не имеют этой странной анимации. Даже странно, если вкладка содержит UINavigationController
, то она также не имеет этой анимации. Это буквально просто, если прямой ребенок - UINavigationController
.
Кто-нибудь испытывал это раньше? А вам удалось остановить странную анимацию?