iOS - 用动画更换根视图控制器

9

我将通过按下一个按钮来更改根视图控制器,该按钮连接到一个自定义segue,以切换到我想要更改的视图控制器。自定义segue如下:

- (void)perform{
    UIViewController *source = (UIViewController *)self.sourceViewController;
    source.view.window.rootViewController = self.destinationViewController;
}

但这样只会立即更改根视图控制器。我希望该控制器能够在旧的控制器之上淡入。


可能是重复的问题:如何在视图控制器之间实现淡入/无过渡效果 - BangOperator
你的代码隐藏了导航栏。 - dev4life
4个回答

22

常见的做法是:

    UIStoryboard *sb = [UIStoryboard storyboardWithName:@"YourSBName" bundle:nil];
    UIViewController *vc = [sb instantiateInitialViewController];// Or any VC with Id
    DictateITAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    appDelegate.window.rootViewController = vc; // PLEASE READ NOTE ABOUT THIS LINE
    [UIView transitionWithView:appDelegate.window
                      duration:INTERVAL_DURATION
                       options:UIViewAnimationOptionTransitionCrossDissolve
                    animations:^{ appDelegate.window.rootViewController = vc; }
                    completion:nil];

现在有关的一些注释:

appDelegate.window.rootViewController = vc; // PLEASE READ NOTE ABOUT THIS LINE

实例化的新视图控制器将在默认方向即纵向呈现。因此,如果您在横向模式下执行此操作,则新的视图控制器将显示为纵向,然后转为横向。这行代码解决了我的问题。


3
我认为已经有很多答案了,但是像这样的内容应该行得通:

[UIView transitionWithView:self.sourceViewController.view.window
                  duration:0.5
                   options:UIViewAnimationOptionTransitionCrossDissolve
                animations:^{
                    self.sourceViewController.view.window.rootViewController = self.destinationViewController;
                } completion:^(BOOL finished) {
                    // Code to run after animation
                }];

2

我需要将这个转换成Swift 3.0版本,用于我的当前项目。以下是一种方法:

//Get the storyboard that contains the VC you want
let storyboard = UIStoryboard(name: "Main", bundle: nil)

//Get the VC you want to push onto the stack
//You can use storyboard.instantiateViewController(withIdentifier: "yourStoryboardId")
guard let vc = storyboard.instantiateInitialViewController() else { return }

//Get the current app delegate 
guard let appDel = UIApplication.shared.delegate as? AppDelegate else { return }

//Set the current root controller and add the animation with a
//UIView transition
appDel.window?.rootViewController = vc

UIView.transition(with: appDel.window!,
              duration: 0.25,
               options: .transitionCrossDissolve,
            animations: { appDel.window?.rootViewController = vc } ,
            completion: nil)

-3

这不会改变根视图控制器,它会将一个新的视图控制器添加到堆栈中。你不会多次使用此方法来释放内存。 - LightMan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接