zoukankan      html  css  js  c++  java
  • iOS(视图控制器转场)

    转场需要提供转场代理,不使用默认的代理则需要自己实现代理方式,有UINavigationController、UITabBarController、UIViewController三种代理,实现以下三种协议
    <UINavigationControllerDelegate>     //push和pop切换 <UITabBarControllerDelegate>       //tab切换
    <UIViewControllerTransitioningDelegate>  //UICollectionViewController 与 UINavigationController 结合的转场方式

    转场触发时,需要UIKit 将要求转场代理将提供转场动画的核心构件:动画控制器和交互控制器


    动画控制器(Animation Controller):

     最重要的部分,负责添加视图以及执行动画;遵守<UIViewControllerAnimatedTransitioning>协议;由我们实现。

      

     交互控制器

     通过交互手段,通常是手势来驱动动画控制器实现的动画,使得用户能够控制整个过程;遵守<UIViewControllerInteractiveTransitioning>协议;系统已经打包好现成的类供我们使用

       转场环境(Transition Context):

       提供转场中需要的数据;遵守<UIViewControllerContextTransitioning>协议;由 UIKit 在转场开始前生成并提供给我们提交的动画控制 器和交互控制器使用。

      

     转场协调器(Transition Coordinator):

    可在转场动画发生的同时并行执行其他的动画,其作用与其说协调不如说辅助,主要在 Modal 转场和交互转场取消时使用,其他时候很少用到;遵守<UIViewControllerTransitionCoordinator>协议;由 UIKit 在转场时生成,UIViewController 在 iOS 7 中新增了方法transitionCoordinator()返回一个遵守该协议的对象,且该方法只在该控制器处于转场过程中才返回一个此类对象,不参与转场时返回 nil

    动画控制器协议实现:
     
     
    
    

    //返回动画时间

    
    

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

    
    

        

    
    

        return self.duration;

    
    

    }

    
    

     

    
    

    //执行动画

    
    

    - (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/


      

  • 相关阅读:
    发现一个奇怪的问题: 不能把文件取名为 con
    博客园新购服务器硬件配置
    [重要新功能]团队Blog
    [庆祝]博客园已迁至新服务器
    [公告]博客园论坛开放注册
    博客园出现了奇怪的cookie问题
    [公告]博客园聊天室试运行
    [重发]请为你喜欢的博客园杂志的名字投上一票
    [征询意见]准备采用“创作共用”协议保护大家的原创作品
    博客园期刊制作小组Blog开通
  • 原文地址:https://www.cnblogs.com/air-liyan/p/6164021.html
Copyright © 2011-2022 走看看