Skip to content

Instantly share code, notes, and snippets.

@gimenete
Last active July 31, 2020 16:20
Show Gist options
  • Star 44 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save gimenete/53704124583b5df3b407 to your computer and use it in GitHub Desktop.
Save gimenete/53704124583b5df3b407 to your computer and use it in GitHub Desktop.
Animated rootViewController transition
// put this in your AppDelegate
- (void)changeRootViewController:(UIViewController*)viewController {
if (!self.window.rootViewController) {
self.window.rootViewController = viewController;
return;
}
UIView *snapShot = [self.window snapshotViewAfterScreenUpdates:YES];
[viewController.view addSubview:snapShot];
self.window.rootViewController = viewController;
[UIView animateWithDuration:0.3 animations:^{
snapShot.layer.opacity = 0;
snapShot.layer.transform = CATransform3DMakeScale(1.5, 1.5, 1.5);
} completion:^(BOOL finished) {
[snapShot removeFromSuperview];
}];
}
@olivaresf
Copy link

Works beautifully. Thanks!

@hirenpanchal1608
Copy link

Hello,

I want to do it in my viewcontroller, not in appdelegate.
And in my viewcontroller i have applied this code with necessary changes, but it is not working,

My code is :

UIViewController *rootViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"];

UIView *snapShot = [self.view.window snapshotViewAfterScreenUpdates:YES];
[self.view addSubview:snapShot];
self.view.window.rootViewController = rootViewController;
[UIView animateWithDuration:1 animations:^{
    snapShot.layer.opacity = 0;
    snapShot.layer.transform = CATransform3DMakeScale(1.5, 1.5, 1.5);
} completion:^(BOOL finished) {
    [snapShot removeFromSuperview];
}];

@swainet
Copy link

swainet commented May 26, 2015

mark, great!

@rtimpone
Copy link

Nice, this works great! I actually ended up implementing this as a category on UIWindow:

@interface UIWindow (Additions)

- (void)setRootViewController: (UIViewController *)rootViewController animated: (BOOL)animated;

@end

@implementation UIWindow (Additions)

- (void)setRootViewController: (UIViewController *)rootViewController animated: (BOOL)animated
{
    UIView *snapShotView;

    if (animated)
    {
        snapShotView = [self snapshotViewAfterScreenUpdates: YES];
        [rootViewController.view addSubview: snapShotView];
    }

    [self setRootViewController: rootViewController];

    if (animated)
    {
        [UIView animateWithDuration: 0.3 animations:^{

            snapShotView.layer.opacity = 0;
            snapShotView.layer.transform = CATransform3DMakeScale(1.5, 1.5, 1.5);

        } completion:^(BOOL finished) {

            [snapShotView removeFromSuperview];

        }];
    }
}

@end

And in the app delegate, I used it like this:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName: @"Main" bundle: nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier: @"controllerIdentifier"];
[self.window setRootViewController: vc animated: YES];

@Bodacious
Copy link

Nice!

@AakifNadeem
Copy link

AakifNadeem commented Jul 31, 2020

Try this out!

let sb = UIStoryboard(name: "Main", bundle: nil)
let VC = sb.instantiateViewController(withIdentifier: "LoginViewController") as! LoginViewController
let navRootView = UINavigationController(rootViewController: VC)
self.present(navRootView, animated: true, completion: nil)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment