iOS(視圖控制器轉場)

轉場須要提供轉場代理,不使用默認的代理則須要本身實現代理方式,有UINavigationController、UITabBarController、UIViewController三種代理,實現如下三種協議
<UINavigationControllerDelegate>     //push和pop切換 <UITabBarControllerDelegate>       //tab切換
<UIViewControllerTransitioningDelegate>  //UICollectionViewController 與 UINavigationController 結合的轉場方式

轉場觸發時,須要UIKit 將要求轉場代理將提供轉場動畫的核心構件:動畫控制器和交互控制器


動畫控制器(Animation Controller):

 最重要的部分,負責添加視圖以及執行動畫;遵照<UIViewControllerAnimatedTransitioning>協議;由咱們實現。html

  

 交互控制器ios

 經過交互手段,一般是手勢來驅動動畫控制器實現的動畫,使得用戶可以控制整個過程;遵照<UIViewControllerInteractiveTransitioning>協議;系統已經打包好現成的類供咱們使用app

 

   轉場環境(Transition Context):dom

   提供轉場中須要的數據;遵照<UIViewControllerContextTransitioning>協議;由 UIKit 在轉場開始前生成並提供給咱們提交的動畫控制 器和交互控制器使用。ide

  

 轉場協調器(Transition Coordinator):動畫

可在轉場動畫發生的同時並行執行其餘的動畫,其做用與其說協調不如說輔助,主要在 Modal 轉場和交互轉場取消時使用,其餘時候不多用到;遵照<UIViewControllerTransitionCoordinator>協議;由 UIKit 在轉場時生成,UIViewController 在 iOS 7 中新增了方法transitionCoordinator()返回一個遵照該協議的對象,且該方法只在該控制器處於轉場過程當中才返回一個此類對象,不參與轉場時返回 nilui

動畫控制器協議實現:
 
 
 
  

//返回動畫時間this

 
  

- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {spa

 
  

    

 
  

    return self.duration;3d

 
  

}

 
  

 

 
  

//執行動畫

 
  

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {

 
  

    //返回容器視圖,轉場發生的地方

 
  

    //獲取參與轉場的視圖控制器,有 UITransitionContextFromViewControllerKey UITransitionContextToViewControllerKey 兩個 Key

 
  

    //經過viewForKey:獲取的視圖是viewControllerForKey:返回的控制器的根視圖,或者 nilviewForKey:方法返回 nil 只有一種狀況: UIModalPresentationCustom 模式下的 Modal 轉場 ,經過此方法獲取 presentingView 時獲得的將是 nil,在後面的 Modal 轉場裏會詳細解釋。

 
  

    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

 
  

    UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

 
  

    UIView *toView = toVC.view;

 
  

    UIView *fromView = fromVC.view;

 
  

    

 
  

    [self animateTransition:transitionContext fromVC:fromVC toVC:toVC fromView:fromView toView:toView];

 
  

}

 
 

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext fromVC:(UIViewController *)fromVC toVC:(UIViewController *)toVC fromView:(UIView *)fromView toView:(UIView *)toView {

    

    // Add the toView to the container

    UIView* containerView = [transitionContext containerView];

    [containerView addSubview:toView];

    [containerView sendSubviewToBack:toView];

    

    CGSize size = toView.frame.size;

    

    NSMutableArray *snapshots = [NSMutableArray new];

    

    CGFloat xFactor = 10.0f;

    CGFloat yFactor = xFactor * size.height / size.width;

    

    // snapshot the from view, this makes subsequent snaphots more performant

    UIView *fromViewSnapshot = [fromView snapshotViewAfterScreenUpdates:NO];

    

    // create a snapshot for each of the exploding pieces

    for (CGFloat x=0; x < size.width; x+= size.width / xFactor) {

        for (CGFloat y=0; y < size.height; y+= size.height / yFactor) {

            CGRect snapshotRegion = CGRectMake(x, y, size.width / xFactor, size.height / yFactor);

            UIView *snapshot = [fromViewSnapshot resizableSnapshotViewFromRect:snapshotRegion  afterScreenUpdates:NO withCapInsets:UIEdgeInsetsZero];

            snapshot.frame = snapshotRegion;

            [containerView addSubview:snapshot];

            [snapshots addObject:snapshot];

        }

    }

    

    [containerView sendSubviewToBack:fromView];

    

    // animate

    NSTimeInterval duration = [self transitionDuration:transitionContext];

    [UIView animateWithDuration:duration animations:^{

        for (UIView *view in snapshots) {

            CGFloat xOffset = [self randomFloatBetween:-100.0 and:100.0];

            CGFloat yOffset = [self randomFloatBetween:-100.0 and:100.0];

            view.frame = CGRectOffset(view.frame, xOffset, yOffset);

            view.alpha = 0.0;

            view.transform = CGAffineTransformScale(CGAffineTransformMakeRotation([self randomFloatBetween:-10.0 and:10.0]), 0.01, 0.01);

        }

    } completion:^(BOOL finished) {

        for (UIView *view in snapshots) {

            [view removeFromSuperview];

        }

        [transitionContext completeTransition:![transitionContext transitionWasCancelled]];

    }];

    

}

 

- (float)randomFloatBetween:(float)smallNumber and:(float)bigNumber {

    float diff = bigNumber - smallNumber;

    return (((float) (arc4random() % ((unsigned)RAND_MAX + 1)) / RAND_MAX) * diff) + smallNumber;

}

 

 

參考連接:http://blog.devtang.com/2016/03/13/iOS-transition-guide/

相關文章
相關標籤/搜索