如何在 UINavigationController 屏幕转换时翻转整个屏幕?

How to flip the whole screen at UINavigationController screen transition?

我有一个可以在任何屏幕上访问的注销按钮,当点击时,我想弹出当前在导航控制器堆栈上的所有视图控制器,并以根目录更改为登录屏幕导航控制器的视图控制器。但我希望过渡就像翻转整个屏幕一样。

我看到一些代码说要使用:

UIView.transitionFromView(frontView, toView: backView, duration: 1, options: UIViewAnimationOptions.TransitionFlipFromRight | UIViewAnimationOptions.ShowHideTransitionViews, completion: nil)

但这只是过渡一个 UIView,而不是整个屏幕。

此外,如果我提供 self.view 作为 frontView,这可能可以用来改变整个屏幕,但这意味着我只改变当前顶视图控制器的 frontView,而不改变任何东西导航控制器中的视图控制器堆栈。

如何翻转整个屏幕,同时改变导航控制器的堆栈?

我想可能有这样的代码:

func logout() {
    let loginVc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "login")
    UIView.animate (duration: 0.3, options: UIViewAnimationOptions.TransitionFlipFromRight) {
        self.navigationController?.viewControllers = [loginVc];
    }
}

我已经试过了,但是变化是瞬间发生的,而不是动画。

谢谢。

编辑:

澄清一下我想要什么,我想要来自:

UINavigationController with stack: [Vc1, Vc2, Vc3, Vc4, Vc5, ...]

收件人:

UINavigationController with stack: [LoginVc]

使用整个屏幕翻转动画。

这是通过弹出到 root 还是替换堆栈或完全替换 UINavigationController 来完成的,无论它是使用 UIView.animate 还是 UIView.transitionFromView 或其他,或者以上的任何组合,这取决于帮助解决方案的好人。 :)

您可以通过多种方式完成此操作,最好的解决方案是结合当前的设置方式、您的 UI 允许的内容以及个人偏好。

例如,当用户点击注销按钮时,您可以使用翻转动画以模式方式显示带有登录表单的视图控制器,并将导航弹出到后台的根目录(用户不会看到)。因此,当用户登录时,关闭视图控制器会将用户带到导航的根目录。

另一个选项可能是为根视图控制器提供两种不同的状态。当用户登录时,通常会显示内容。当用户注销时,会显示登录表单。如果视图控制器相对简单,您基本上可以使用 isHidden 属性 来完成此操作。

不管你走什么路线,制作翻转动画最简单的方法是:

guard let nav = navigationController else {
    return
}

UIView.transition(with: nav.view, duration: 0.75, options: .transitionFlipFromLeft, animations: {
    nav.popToRootViewController(animated: false)
}, completion: nil)

您的翻转选项:

.transitionFlipFromLeft
.transitionFlipFromRight
.transitionFlipFromTop
.transitionFlipFromBottom

与所有 UIView 动画方法一样,自引入 UIViewPropertyAnimator 以来,Apple 现在不鼓励使用此方法。但是 UIViewPropertyAnimator 只符合 iOS 10+.