Cambie el RootViewcontroller con el efecto Push Transition

en mi aplicación iOS, necesito cambiar el rootviewController de la window entre aplicaciones. Así que cuando cambio mi rootviewcontroller dincamically es chasquear la vista antes de su cambio. Pero lo que quiero es dar una transición suave cuando se cambia el rootviewcontroller.

Había intentado con la siguiente pero no es la transición que quiero.

[UIView transitionWithView:self.window duration:.8 options:UIViewAnimationOptionTransitionCurlUp animations:^{ self.window.rootViewController = tabBarControllerMain; [self.window makeKeyAndVisible]; } completion:NULL]; 

Quiero una transición específica como la transición pushview del controller de navigation.

¿Puede cualquier cuerpo darme idea de cómo lograrlo?

Basado en la documentation de esta Apple

 UIViewController *viewControllerToBeShown=[[UIViewController alloc]init]; //viewControllerToBeShown.view.frame = self.view.frame; viewControllerToBeShown.view.backgroundColor = [UIColor orangeColor]; AppDelegateClass *yourAppDelegate =(AppDelegateClass*)[UIApplication shanetworkingApplication].delegate; UIView *myView1 = yourAppDelegate.window.rootViewController.view; UIView *myView2 = viewControllerToBeShown.view; myView2.frame = yourAppDelegate.window.bounds; [yourAppDelegate.window addSubview:myView2]; CATransition* transition = [CATransition animation]; transition.startProgress = 0; transition.endProgress = 1.0; transition.type = kCATransitionPush; transition.subtype = kCATransitionFromRight; transition.duration = 5.0; // Add the transition animation to both layers [myView1.layer addAnimation:transition forKey:@"transition"]; [myView2.layer addAnimation:transition forKey:@"transition"]; myView1.hidden = YES; myView2.hidden = NO; yourAppDelegate.window.rootViewController = viewControllerToBeShown; 

Rápido

  guard let appDelegate = UIApplication.shanetworking.delegate, let appDelegateWindow = appDelegate.window, let appDelegateView = window.rootViewController?.view, let viewContollersView = viewController.view else { return } viewContollersView.frame = (appDelegateWindow?.bounds)! appDelegate.window??.addSubview(viewContollersView) let transition = CATransition() transition.startProgress = 0 transition.endProgress = 1.0 transition.type = kCATransitionPush transition.subtype = kCATransitionFromRight transition.duration = 0.35 appDelegateView.layer.add(transition, forKey: "transition") viewContollersView.layer.add(transition, forKey: "transition") appDelegateView.isHidden = true viewContollersView.isHidden = false appDelegateWindow?.rootViewController = viewController 

Aquí hay un código en Swift sobre cómo hacer la animation Push y Pop en rootviewcontroller.

 //Declare enum enum AnimationType{ case ANIMATE_RIGHT case ANIMATE_LEFT case ANIMATE_UP case ANIMATE_DOWN } // Create Function... func showViewControllerWith(newViewController:UIViewController, usingAnimation animationType:AnimationType) { let currentViewController = UIApplication.shanetworkingApplication().delegate?.window??.rootViewController let width = currentViewController?.view.frame.size.width; let height = currentViewController?.view.frame.size.height; var previousFrame:CGRect? var nextFrame:CGRect? switch animationType { case .ANIMATE_LEFT: previousFrame = CGRectMake(width!-1, 0.0, width!, height!) nextFrame = CGRectMake(-width!, 0.0, width!, height!); case .ANIMATE_RIGHT: previousFrame = CGRectMake(-width!+1, 0.0, width!, height!); nextFrame = CGRectMake(width!, 0.0, width!, height!); case .ANIMATE_UP: previousFrame = CGRectMake(0.0, height!-1, width!, height!); nextFrame = CGRectMake(0.0, -height!+1, width!, height!); case .ANIMATE_DOWN: previousFrame = CGRectMake(0.0, -height!+1, width!, height!); nextFrame = CGRectMake(0.0, height!-1, width!, height!); } newViewController.view.frame = previousFrame! UIApplication.shanetworkingApplication().delegate?.window??.addSubview(newViewController.view) UIView.animateWithDuration(0.33, animations: { () -> Void in newViewController.view.frame = (currentViewController?.view.frame)! currentViewController?.view.frame = nextFrame! }) { (fihish:Bool) -> Void in UIApplication.shanetworkingApplication().delegate?.window??.rootViewController = newViewController } } // call the func for ANIMATE_LEFT or ANIMATE_RIGHT etc self.showViewControllerWith(rootViewController, usingAnimation: AnimationType.ANIMATE_LEFT) 

Espero que esto ayude…

Basándome en la respuesta de Hardik Darji, he creado la extensión UIWindow para intercambiar rootViewController con un tipo de animation configurable que simula animaciones del sistema: push, pop, present y dismiss.

Swift 3.

 public enum SwapRootVCAnimationType { case Push case Pop case Present case Dismiss } extension UIWindow { public func swapRootViewControllerWithAnimation(newViewController:UIViewController, animationType:SwapRootVCAnimationType, completion: (() -> ())? = nil) { guard let currentViewController = rootViewController else { return } let width = currentViewController.view.frame.size.width; let height = currentViewController.view.frame.size.height; var newVCStartAnimationFrame: CGRect? var currentVCEndAnimationFrame:CGRect? var newVCAnimated = true switch animationType { case .Push: newVCStartAnimationFrame = CGRect(x: width, y: 0, width: width, height: height) currentVCEndAnimationFrame = CGRect(x: 0 - width/4, y: 0, width: width, height: height) case .Pop: currentVCEndAnimationFrame = CGRect(x: width, y: 0, width: width, height: height) newVCStartAnimationFrame = CGRect(x: 0 - width/4, y: 0, width: width, height: height) newVCAnimated = false case .Present: newVCStartAnimationFrame = CGRect(x: 0, y: height, width: width, height: height) case .Dismiss: currentVCEndAnimationFrame = CGRect(x: 0, y: height, width: width, height: height) newVCAnimated = false } newViewController.view.frame = newVCStartAnimationFrame ?? CGRect(x: 0, y: 0, width: width, height: height) addSubview(newViewController.view) if !newVCAnimated { bringSubview(toFront: currentViewController.view) } UIView.animate(withDuration: 0.3, delay: 0, options: [.curveEaseOut], animations: { if let currentVCEndAnimationFrame = currentVCEndAnimationFrame { currentViewController.view.frame = currentVCEndAnimationFrame } newViewController.view.frame = CGRect(x: 0, y: 0, width: width, height: height) }, completion: { finish in self.rootViewController = newViewController completion?() }) makeKeyAndVisible() } 

}