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

时间:2022-02-16 09:27:14

I'm changing the root view controller by pressing a button which is hooked up to a custom segue to the view controller that I want to change to. The custom segue looks like:

我正在通过按下一个连接到我想要更改为的视图控制器的自定义segue的按钮来更改根视图控制器。自定义segue看起来像:

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

But this just immediately changes the root view controller. I'd like the controller to fade on top of the old controller.

但这只会立即更改根视图控制器。我希望控制器在旧控制器之上淡出。

4 个解决方案

#1


20  

The common way to do that is:

常见的方法是:

    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];

Now a few notes about:

现在有几点说明:

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

The new view controller, you instantiate will be presented in the default orientation i.e. portrait. So probably if you do that in landscape your new view controller will appear as portrait and then turns to landscape. This line fixed this issue for me.

您实例化的新视图控制器将以默认方向显示,即纵向。因此,如果您在横向中执行此操作,则新视图控制器将显示为纵向,然后转为横向。这条线为我解决了这个问题。

#2


3  

I think there are many answers for this already, but something like this should work:

我认为已经有很多答案,但这样的事情应该有效:

[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
                }];

#3


2  

I needed to translate this into Swift 3.0 for my current project. Here's a way to do that:

我需要将其转换为我当前项目的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)

#4


-3  

The easiest way is:

最简单的方法是:

[sourceViewController presentViewController:destinationViewController animated:YES completion:nil];

[sourceViewController presentViewController:destinationViewController animated:YES completion:nil];

More about it: https://developer.apple.com/library/ios/featuredarticles/viewcontrollerpgforiphoneos/ModalViewControllers/ModalViewControllers.html

更多信息:https://developer.apple.com/library/ios/featuredarticles/viewcontrollerpgforiphoneos/ModalViewControllers/ModalViewControllers.html

#1


20  

The common way to do that is:

常见的方法是:

    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];

Now a few notes about:

现在有几点说明:

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

The new view controller, you instantiate will be presented in the default orientation i.e. portrait. So probably if you do that in landscape your new view controller will appear as portrait and then turns to landscape. This line fixed this issue for me.

您实例化的新视图控制器将以默认方向显示,即纵向。因此,如果您在横向中执行此操作,则新视图控制器将显示为纵向,然后转为横向。这条线为我解决了这个问题。

#2


3  

I think there are many answers for this already, but something like this should work:

我认为已经有很多答案,但这样的事情应该有效:

[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
                }];

#3


2  

I needed to translate this into Swift 3.0 for my current project. Here's a way to do that:

我需要将其转换为我当前项目的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)

#4


-3  

The easiest way is:

最简单的方法是:

[sourceViewController presentViewController:destinationViewController animated:YES completion:nil];

[sourceViewController presentViewController:destinationViewController animated:YES completion:nil];

More about it: https://developer.apple.com/library/ios/featuredarticles/viewcontrollerpgforiphoneos/ModalViewControllers/ModalViewControllers.html

更多信息:https://developer.apple.com/library/ios/featuredarticles/viewcontrollerpgforiphoneos/ModalViewControllers/ModalViewControllers.html