过渡到 UINavigationController 中嵌入的新 ViewController 会导致动画问题

Transition to a new ViewController embedded in an UINavigationController causes animation problem

我使用一个 rootViewController,我想移动到另一个 ViewController。向新ViewController 的过渡适用于该代码。

当新ViewController 嵌入 UINavigationController 时出现问题。然后导航栏在动画的过程中是动态的,并且改变位置。

导航栏正在从左上角移动到正确位置。

fileprivate func animateTransition(to newViewController: UIViewController) {
    currentViewController.willMove(toParent: nil)
    addChild(newViewController)
    newViewController.view.frame = view.bounds
    transition(from: currentViewController, to: newViewController, duration: 2, options: [.transitionCrossDissolve, .curveEaseOut], animations: {
        self.currentViewController.removeFromParent()
        newViewController.didMove(toParent: self)
        self.currentViewController = newViewController
    }, completion: nil)
}

如何使用 "fade" 动画移动到另一个 UINavigationController?导航栏如何从动画开始就位于正确的位置?

试着把它放在新ViewController

的class声明下面
override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationController?.setNavigationBarHidden(false, animated: false)
}

如果您的 ViewController 中已经有一个 viewDidLoad(),那么只需使用最后一部分。

如果这不起作用,请告诉我。

首先,您应该将视图控制器清理代码调用从 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
})

这将允许它从一开始就正确显示导航栏,然后淡入。