使用动画交换rootViewController

edc*_*591 33 cocoa-touch objective-c uiviewcontroller ios

我在使用动画交换rootViewControllers方面遇到了一些麻烦.这是我正在使用的代码:

[UIView transitionWithView:self.window duration:0.8 options:UIViewAnimationOptionTransitionFlipFromRight animations:^{
        self.window.rootViewController = self.navigationController;
    } completion:nil];
Run Code Online (Sandbox Code Playgroud)

除了在动画之前,屏幕变成黑色然后动画发生之外,它有点工作.看起来原始的rootViewController在动画之前就被删除了.有任何想法吗?

XJo*_*nes 50

transitionWithView用于为指定容器视图的子视图设置动画.更改根视图控制器的动画并不是那么简单.我花了很长时间试图做它没有副作用.看到:

在不使用导航控制器堆栈,子视图或模态控制器的情况下更改视图控制器的动画?

编辑:添加参考答案的摘录

[UIView transitionFromView:self.window.rootViewController.view
                    toView:viewController.view
                  duration:0.65f
                   options:transition
                completion:^(BOOL finished){
                    self.window.rootViewController = viewController;
                }];
Run Code Online (Sandbox Code Playgroud)


Mar*_*ski 44

我知道这是一个相当古老的问题,然而,接受的答案和替代方案都没有提供一个好的解决方案(当动画完成新的根视图控制器的导航栏从白色闪烁到背景颜色,这是非常刺耳的) .

我通过快照第一个视图控制器的最后一个屏幕,将其覆盖在第二个(目标)视图控制器上,然后我将第二个视图控制器设置为root 按照我想要的方式设置动画来修复此问题:

UIView *overlayView = [[UIScreen mainScreen] snapshotViewAfterScreenUpdates:NO];
[self.destinationViewController.view addSubview:overlayView];
self.window.rootViewController = self.destinationViewController;

[UIView animateWithDuration:0.4f delay:0.0f options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
    overlayView.alpha = 0;
} completion:^(BOOL finished) {
    [overlayView removeFromSuperview];
}];
Run Code Online (Sandbox Code Playgroud)

编辑: Swift 3版本的代码:

let overlayView = UIScreen.main.snapshotView(afterScreenUpdates: false)
destinationViewController.view.addSubview(overlayView)
window.rootViewController = destinationViewController

UIView.animate(withDuration: 0.4, delay: 0, options: .transitionCrossDissolve, animations: {
    overlayView.alpha = 0
}, completion: { finished in
    overlayView.removeFromSuperview()
})
Run Code Online (Sandbox Code Playgroud)


nac*_*oss 5

我找到transitionWithView:duration:options:animations:completion:产生更可靠的结果.

[UIView transitionWithView:window
                  duration:0.3
                   options:UIViewAnimationOptionTransitionFlipFromLeft
                animations:^{
                    [fromView removeFromSuperview];
                    [window addSubview:toView];
                    window.rootViewController = toViewController;
                }
                completion:NULL];
Run Code Online (Sandbox Code Playgroud)

如果您将其保留到完成块以设置根视图控制器,则在视图(将/将出现)等方法期间出现

self.view.window.rootViewController
Run Code Online (Sandbox Code Playgroud)

仍将设置为上一个视图控制器.在大多数情况下,这可能不是问题,除非你需要像我一样在这些方法中将对rootViewController的引用传递给其他代码.