Во-первых, вы должны переместить вызов кода очистки контроллера представления из замыкания animations
в замыкание completion
:
currentViewController.willMove(toParent: nil)
addChild(newViewController)
newViewController.view.frame = view.bounds
transition(from: currentViewController, to: newViewController, duration: 2, options: [.transitionCrossDissolve, .curveEaseOut], animations: {
// this is intentionally blank
}, completion: { _ in
self.currentViewController.removeFromParent()
newViewController.didMove(toParent: self)
self.currentViewController = newViewController
})
Вы не хотите указывать, что переход выполнен доанимация завершена.
Что касается проблемы с панелью навигации, вместо того, чтобы transition(from:to:duration:...)
обрабатывать манипуляции с иерархией контроллера представления, вы можете добавить ее в иерархию представлений и затем анимировать ее отображение.Обычно вы используете опцию .showHideTransitionViews
, но transition
все еще делает что-то любопытное с методами внешнего вида, которые сбивают с толку навигационный контроллер, поэтому лучше просто анимировать его самостоятельно:
currentViewController.willMove(toParent: nil)
addChild(newViewController)
newViewController.view.frame = view.bounds
newViewController.view.alpha = 0
view.addSubview(newViewController.view)
UIView.animate(withDuration: 2, delay: 0, options: .curveEaseOut, animations: {
newViewController.view.alpha = 1
}, completion: { _ in
self.currentViewController.view.removeFromSuperview()
self.currentViewController.removeFromParent()
newViewController.didMove(toParent: self)
self.currentViewController = newViewController
})
Этопозволит ему правильно представить навигационную панель с самого начала и просто добавить ее.