iOS-4步搞定自定义转场动画

作者: 鲲鹏DP | 来源:发表于2016-08-26 01:32 被阅读2879次

    1.系统提供的转场动画

    目前,系统给我们提供了push/pops和present/dismiss两种控制器之间跳转方.当然,通过设置UIModalTransitionStyle属性,可以实现下面4种modal效果,相信大家都比较熟悉了,这里就不再展示效果图.

     UIModalTransitionStyleCoverVertical         // 从下往上,
     UIModalTransitionStyleFlipHorizontal        // 水平翻转
     UIModalTransitionStyleCrossDissolve         // 淡入淡出
     UIModalTransitionStylePartialCurl           // 卷角翻页
    

    2.自定义转场动画使用场景

    系统给我们提供的转场动画效果较少,并且有时想对系统的效果做一些修改.例如:我们使用淡入淡出的modal效果,系统的动画时间我们不满意,希望让动画快点,或者慢点.系统并没有给我提供直接修改的属性或者方法,那么,这时我们不得不考虑使用自定义转场动画来实现我们想要的效果.


    3.自定义转场动画的实现步骤

    第1步:设置需要弹出控制器的modalPresentationStyle为UIModalPresentationCustom

      detailVc.modalPresentationStyle = UIModalPresentationCustom;
    

    第2步:设置转场代理

    detailVc.transitioningDelegate = self
    
    • 可以抽一个工具类,专门负责转场动画

    第3步:遵守UIViewControllerTransitioningDelegate代理实现两个方法

    • 确定谁负责弹出动画
    
    -(id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
        self.isPresnted = YES;
        return self;
    }
    
    • 确定谁负责动画消失
    - (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
        self.isPresnted = NO;
        return self;
    }
    

    第4步:实现转场动画

    上面都返回self,说明当前控制器即负责弹出动画又负责动画消失,所以具体的转场动画在当前控制器中进行.

    • 先确定转场动画时间间隔
    - (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
        return 1.0;
    }
    
    • 再实现具体动画(由于当前控制器即负责弹出动画,又负责消失动画,所以定义一个Bool类型属性isPresnted加以区分)
    - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
        
        if (self.isPresnted == YES) {
           //这里做弹出动画
            
        } else {
         
       //这里做消失动画
        }
    }
    

    小结:

    也可以让不同的控制器分别负责弹出和消失动画,这样就不需要定义一个专门用于区分的属性.个人建议最好是抽取一个专门负责转场动画的工具类,让该工具类负责所有转场动画,这样,不管是从业务逻辑上还是代码的复用性上都更加好.当然,这样做存在的一个弊端就是,转场动画中需要用到的一些属性必须通过定义变量,代理和Block等方式传递进来,而使用不同的控制器来管理弹出和消失动画在获取属性上更加方便.具体怎样做,也就仁者见仁,智者见智了.


    下面来具体实现一个转场动画效果吧

    ** 由于实现动画的核心代码在第四步,这里也就只看animateTransition:这一个方法啦!**

    • 从上往下的Modal效果
    - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
        
        if (self.isPresnted == YES) {
            //1.取出view
            UIView *presentedView = [transitionContext viewForKey:UITransitionContextToViewKey];
            //2.放入containerView
            [[transitionContext containerView]addSubview:presentedView];
            //3.设置基本属性
            presentedView.frame = CGRectMake(0, -667, 375, 667);
            //4.动画
            [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
              presentedView.frame = CGRectMake(0, 0, 375, 667);
            }completion:^(BOOL finished) {
                [transitionContext completeTransition:YES];
            }];
            
        } else {
            //1.取出view
            UIView *dismissedView = [transitionContext viewForKey:UITransitionContextFromViewKey];
            //2.放入containerView
            [[transitionContext containerView]addSubview:dismissedView];
     
            //3.动画
            [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
                dismissedView.frame =CGRectMake(0, -667, 375, 667);
            }completion:^(BOOL finished) {
                
                [transitionContext completeTransition:YES];
            }];
            
        }
    }
    
    modal1.gif
    • 模仿系统淡入淡出效果
    - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
        
        if (self.isPresnted == YES) {
            //1.取出view
            UIView *presentedView = [transitionContext viewForKey:UITransitionContextToViewKey];
            //2.放入containerView
            [[transitionContext containerView]addSubview:presentedView];
            //3.设置基本属性
            presentedView.alpha = 0;
            //4.动画
            [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
                presentedView.alpha = 1.0;
            }completion:^(BOOL finished) {
                [transitionContext completeTransition:YES];
                
            }];
            
        } else {
            //1.取出view
            UIView *dismissedView = [transitionContext viewForKey:UITransitionContextFromViewKey];
            //2.放入containerView
            [[transitionContext containerView]addSubview:dismissedView];
            //3.设置基本属性
            dismissedView.alpha = 1;
            //4.动画
            [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
                dismissedView.alpha = 0;
            }completion:^(BOOL finished) {
                
                [transitionContext completeTransition:YES];
            }];
        }
    }
    
    
    淡入淡出.gif

    小结:

    • 动画的时间可以从ransitionDuration:方法获取
    • 通过UITransitionContextToViewKey和UITransitionContextFromViewKey两个Key分别获取弹出和消失动画的View(注意别混淆两个Key)
    • 要将做动画的View加入到专门用于动画的containerView中
      这里只介绍怎样实现转场动画,至于其他好玩NB的效果,大家可以自己试着实现,后面我也会抽时间研究其他效果

    相关文章

      网友评论

      • PGOne爱吃饺子:大佬 大佬 ,可以问你一个问题么,也是转场动画的问题
      • BETOMElo:写的太好了 一下就看懂了
      • sealife:可以提供一个demo吗?感谢感谢
        sealife:@鲲鹏DP 写出来了,谢谢
        鲲鹏DP:@sealife 应该很详细了吧,按着步骤来就好了,demo现在估计是找不到了的

      本文标题:iOS-4步搞定自定义转场动画

      本文链接:https://www.haomeiwen.com/subject/qrtnsttx.html