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/

相关文章
相关标签/搜索