动画根视图控制器嵌入到以模态呈现的导航控制器中

时间:2021-01-26 10:38:53

标签: ios swift animation

我需要为 UIViewController 设置动画,它是 UINavigationController 的根。该导航控制器以模态方式呈现。 我知道我可以使用视图控制器的生命周期方法来做到这一点,但如果可能的话,我想使用 UIViewControllerAnimatedTransitioning 来保持 VC 代码的整洁。

我尝试了以下方法:

a) 将 UINavigationControllerDelegate 设置为导航控制器,以便我可以使用此委托函数:

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

但是,它仅在导航控制器内的转换期间(从 VC 到 VC)被调用。

b) 在根视图控制器中设置一个 UIViewControllerTransitioningDelegate 并使用这个委托函数:

func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning?

但同样,它不会被调用,因为呈现的是导航控制器。

c) 在导航控制器中设置一个 UIViewControllerTransitioningDelegate 并使用相同的委托函数:

func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning?

在这种情况下,它被调用并且我可以注入 UIViewControllerAnimatedTransitioning 对象,但我只能考虑为根设置动画的技巧,例如

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
    guard let fromVC = transitionContext.viewController(forKey: .from),
          let toVC = transitionContext.viewController(forKey: .to) as? UINavigationController,
          toVC.children.count == 1,
          let myRootVC = toVC.children.first as? MyViewController
    else {
        transitionContext.completeTransition(false)
        return
    }
    // Animate manually
    myRootVC.view.alpha = 0
    // [...]
}

你知道有什么方法可以很好地捕捉到这一点吗?

1 个答案:

答案 0 :(得分:1)

我通过使用 ViewController Containment 将所有 ViewControllers 显示为嵌入式 ViewController 解决了类似问题。

我在启动应用程序时确实有 1 个 RootContainerViewController 设置 - 它只是设置为 rootViewController 没有动画,它只是所有其他 ViewController 的容器。

所有其他 ViewControllers 总是作为 SubViewControllers 和 SubViews 添加到该容器中。

这不仅使您可以将 UIViewControllerAnimatedTransitioning 用于应用程序中的每个过渡,而且还允许您轻松地“重置”应用程序,只需删除 RootContainerViewController 并将其替换为新鲜的。 另一个优点是您可以添加任意数量的 ViewController - 与原生 presentViewController 相比,它一次只能显示 1 个 ViewController。

我尝试过的任何其他方法都以失败告终 - UIViewControllerAnimatedTransitioning 无法直接用于 rootViewController 更改 - 您必须将其与 UIView.animate 结合以支持它。