2014-06-23 46 views
4

在我的iOS應用程序中,我需要更改應用程序.so之間的窗口的rootviewController,當我更改我的rootviewcontroller時,它在切換前切換視圖。但我想要給rootview控制器更改時的平滑過渡。更改具有Push轉換效果的RootViewcontroller

我曾試過以下但它不是我想要的過渡。

[UIView transitionWithView:self.window 
         duration:.8 
         options:UIViewAnimationOptionTransitionCurlUp 
        animations:^{ 

         self.window.rootViewController = tabBarControllerMain; 
    [self.window makeKeyAndVisible]; 
        } 
        completion:NULL]; 

我想要像導航控制器pushview過渡特定的過渡。

可以任何身體給我想法如何實現?

回答

5

Based on this Apple's documentation

UIViewController *viewControllerToBeShown=[[UIViewController alloc]init]; 

//viewControllerToBeShown.view.frame = self.view.frame; 

viewControllerToBeShown.view.backgroundColor = [UIColor orangeColor]; 



AppDelegateClass *yourAppDelegate =(AppDelegateClass*)[UIApplication sharedApplication].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; 

斯威夫特

 guard let appDelegate = UIApplication.shared.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 
+1

這工作然而有沒有辦法爲前視圖 - 控制到不黑?一旦動畫開始,執行代碼的視圖控制器就會變黑。 –

+0

在Swift中,檢查這個答案...它的工作 http://stackoverflow.com/a/35224877/1000906 –

+0

這看起來不像UINavigationController中的過渡,你必須使用一個假的vc –

6

這裏是斯威夫特如何使Push和Pop動畫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.sharedApplication().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.sharedApplication().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.sharedApplication().delegate?.window??.rootViewController = newViewController 
     } 
} 


// call the func for ANIMATE_LEFT or ANIMATE_RIGHT etc 

    self.showViewControllerWith(rootViewController, usingAnimation: AnimationType.ANIMATE_LEFT) 

希望這有助於...

+0

AWEsome?工作! –

4

基礎上Hardik Darji的答案,我已經創建了一個UIWindow擴展交換RootViewController的與模擬系統的動畫配置的動畫類型 - 推,流行,目前和罷免。

斯威夫特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() 
} 

}

+0

完美,但對於Swift 3建議使用低寄存器枚舉案例 –

+0

正是我需要的,謝謝。 – comm1x