2012-01-25 42 views
24

目前我正在使用[self presentModalViewController :newVC animated:YES]。我想從左/右/頂部/底部使用推視效果來呈現newViewcontroller。我試圖使用CATransition,但它在轉換之間顯示一個黑屏。從左/右移動到目前的模型視圖控制器

+0

對於其他人有這個問題,我貼我發現這裏的解決方案:http://stackoverflow.com/questions/6876292/iphone-presentmodalviewcontroller-with-transition-from-right/10842991#10842991 –

回答

1

只有四個UIModalTransitionStyles:

UIModalTransitionStyleCoverVertical 
UIModalTransitionStyleFlipHorizontal 
UIModalTransitionStyleCrossDissolve 
UIModalTransitionStylePartialCurl 

例如:

UIViewController *controller = [[[MyViewController alloc] init] autorelease]; 
UIModalTransitionStyle trans = UIModalTransitionStyleFlipHorizontal; 
[UIView beginAnimations: nil context: nil]; 
[UIView setAnimationTransition: trans forView: [self window] cache: YES]; 
[navController presentModalViewController: controller animated: NO]; 
[UIView commitAnimations]; 
3

我有同樣的問題。說您想從視圖控制器1呈現視圖控制器2在第一視圖控制器使用

[self presentModalViewController: controller animated: NO]]; 

在第二視圖控制器,在viewWillAppear中:方法添加代碼

CATransition *animation = [CATransition animation]; 

    [animation setDelegate:self]; 
    [animation setType:kCATransitionPush]; 
    [animation setSubtype:kCATransitionFromRight]; 

    [animation setDuration:0.40]; 
    [animation setTimingFunction: 
    [CAMediaTimingFunction functionWithName: 
     kCAMediaTimingFunctionEaseInEaseOut]]; 


    [self.view.layer addAnimation:animation forKey:kCATransition]; 

它將工作精細。如果黑屏再次出現,如果您正在使用導航控制器,更換

[self.view.layer addAnimation:animation forKey:kCATransition]; 

[self.navigationController.view.layer addAnimation:animation forKey:kCATransition]; 
+0

試過這個。仍然黑屏問題仍然存在 – user1085093

+0

我也有黑屏問題。出現模式控制器被推入黑屏之前。任何人都解決了問題? – bolonn

90

存在時:

CATransition *transition = [CATransition animation]; 
transition.duration = 0.3; 
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
transition.type = kCATransitionPush; 
transition.subtype = kCATransitionFromRight; 
[self.view.window.layer addAnimation:transition forKey:nil]; 

[self presentModalViewController:viewCtrl animated:NO]; 

當解僱:

CATransition *transition = [CATransition animation]; 
transition.duration = 0.3; 
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
transition.type = kCATransitionPush; 
transition.subtype = kCATransitionFromLeft; 
[self.view.window.layer addAnimation:transition forKey:nil]; 
[self dismissModalViewControllerAnimated:NO]; 
+0

完美。這是正確的答案 – rmvz3

+5

這似乎不再適用於iOS 8,因爲呈現的VC正在移動而不是所呈現的那個。任何想法如何解決它? – Maiaux

+1

¿我如何消除衰落效應? – jalopezsuarez

-1

你可以設置transitioningDelegate在你想要呈現的視圖控制器上。您必須符合UIViewControllerTransitioningDelegateUIViewControllerAnimatedTransitioning協議。通過執行animateTransition(transitionContext: UIViewControllerContextTransitioning),您可以爲視圖控制器子視圖設置動畫。

功能執行過渡

class fromViewController : UIViewController { 
    let transitionManager = TransitionManager() 

    func transitionToViewController() { 
     toController.transitioningDelegate = transitionManager 
     presentViewController(toController, animated: true, completion: nil) 
    } 
} 

然後的TransitionManager看起來像:

import UIKit 

class TransitionManager : UIPercentDrivenInteractiveTransition { 
    var presenting = false 
} 

// MARK: UIViewControllerAnimatedTransitioning 
extension TransitionManager : UIViewControllerAnimatedTransitioning { 
    func animateTransition(transitionContext: UIViewControllerContextTransitioning) { 
     let container = transitionContext.containerView() 
     let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)! 
     let toView = transitionContext.viewForKey(UITransitionContextToViewKey)! 

     let offScreenRight = CGAffineTransformMakeTranslation(container.frame.width, 0) 
     let offScreenLeft = CGAffineTransformMakeTranslation(-container.frame.width, 0) 

     toView.transform = self.presenting ? offScreenRight : offScreenLeft 

     container.addSubview(toView) 
     container.addSubview(fromView) 
     let duration = self.transitionDuration(transitionContext) 

     UIView.animateWithDuration(duration, delay: 0.0, usingSpringWithDamping: 1, initialSpringVelocity: 0.8, options: nil, animations: { 
      fromView.transform = self.presenting ? offScreenLeft : offScreenRight 
      toView.transform = CGAffineTransformIdentity 

      }, completion: { finished in 
      transitionContext.completeTransition(true) 
     }) 
    } 


    func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval { 
     return 0.3 
    } 
} 


// MARK: UIViewControllerTransitioningDelegate 
extension TransitionManager : UIViewControllerTransitioningDelegate { 
    func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
     self.presenting = true 
     return self 
    } 

    func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
     self.presenting = false 
     return self 
    } 
} 
+0

不起作用。 'self.presenting == false'結果出現錯誤框架的黑屏 – Barry

+0

@Barry這對我來說不適用於在不同故事板中的控制器之間使用segues而非手動轉換。通過查看您在上面發佈的代碼,您是試圖覆蓋UINavigationController的推送轉換。故事板設置中的segue是否推動而不是呈現? –

1

X> = 4小時的工作,這工作之後沒有 「撕裂」 或其他背景工件:

class AboutTransition: NSObject, UIViewControllerAnimatedTransitioning { 

    let presenting: Bool 
    let duration: NSTimeInterval 

    init(presenting: Bool, duration: NSTimeInterval = 0.25) { 
     self.presenting = presenting 
     self.duration = duration 
    } 

    @objc func transitionDuration(ctx: UIViewControllerContextTransitioning) -> NSTimeInterval { 
     return duration 
    } 

    @objc func animateTransition(ctx: UIViewControllerContextTransitioning) { 
     let duration = transitionDuration(ctx) 
     let containerView = ctx.containerView() 
     let fromViewController = ctx.viewControllerForKey(UITransitionContextFromViewControllerKey)! 
     let toViewController = ctx.viewControllerForKey(UITransitionContextToViewControllerKey)! 
     let fromView = fromViewController.view // 7.0 & 8.0 compatible vs. viewForKey: 
     let toView = toViewController.view  // 7.0 & 8.0 compatible vs. viewForKey: 

     containerView.addSubview(fromView) 
     containerView.addSubview(toView) 

     let offScreenRight = CGAffineTransformMakeTranslation(containerView.frame.width, 0) 
     let offScreenLeft = CGAffineTransformMakeTranslation(-containerView.frame.width, 0) 

     fromView.transform = CGAffineTransformIdentity 
     toView.transform = self.presenting ? offScreenRight : offScreenLeft 

     UIView.animateWithDuration(duration, delay:0, options:UIViewAnimationOptions(0), animations: { 
      fromView.transform = self.presenting ? offScreenLeft : offScreenRight 
      toView.transform = CGAffineTransformIdentity 

     }, completion: { (finished: Bool) in 
      ctx.completeTransition(finished) 
      if finished { 
       fromView.removeFromSuperview() 
       fromView.frame = toView.frame // reset the frame for reuse, otherwise frame transforms will accumulate 
      } 
     }) 
    } 
} 

然後在AppDelegate.swift

@UIApplicationMain 
class AppDelegate: UIResponder, UIApplicationDelegate, UINavigationControllerDelegate { 

    lazy var window: UIWindow? = { 
     return UIWindow(frame: UIScreen.mainScreen().bounds) 
    }() 

    lazy var storyboard = UIStoryboard(name: "Main", bundle: nil) 

    lazy var nav: UINavigationController = { 
     var r = self.storyboard.instantiateInitialViewController() as! UINavigationController 
     r.delegate = self 
     return r 
    }() 

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 
     self.window!.rootViewController = nav 
     self.window!.makeKeyAndVisible() 

     // .. other setup 

     return true 
    } 

    // ... 


    // MARK: - UINavigationControllerDelegate 

    func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
     // Example of a SettingsViewController which pushes AboutViewController 
     if fromVC is SettingsViewController && toVC is AboutViewController { // Push to About 
      return AboutTransition(presenting: true) 
     } else if fromVC is AboutViewController && toVC is SettingsViewController { // Pop to Settings 
      return AboutTransition(presenting: false) 
     } 
     return nil 
    } 
} 

這是假設一個應用程序正在使用默認的故事板的初始VC作爲UINavigationController

相關問題