zoukankan      html  css  js  c++  java
  • 转场动画

    控制器的转场动画

      众所周知,iOS中的页面跳转方式有两种,一种是navigationController push/pop新页面,另一种是当前页面present/dismiss新页面

      1. push/pop 转场动画

        系统默认的push动画是从右往左推出新视图,pop则是从左往右消失

        自定义实现步骤

          a.控制器实现nagationController delegate的方法animationControllerForOperation:fromController:toController,返回一个实现了UIViewControllerAnimatedTransitionning对象,如果返回为nil,则是系统的默认实现

    - (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC {
        if ([NSStringFromClass(fromVC.class) isEqualTo:]) {
        return [CustomTransitioning new];
      }
        return nil;
    }

          b.自定义实现UIViewControllerAnimatedTransitioning协议的对象,实现自定义转场

    @interface XWPageCoverTransition : NSObject<UIViewControllerAnimatedTransitioning>
    
    @end
    
    @implementation XWPageCoverTransition
    
    - (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
        return 0.3;
    }
    /**
     *  如何执行过渡动画
     */
    - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
        
    }
    
    @end
    

           必须实现该协议的两个方法

          transitionDuration:  返回转场时间

          animationTransition:  转场动画的具体操作,以一个简单的例子来说明如何实现

    // 从下到上显示
    - (void)showFromBottomToTop:(id<UIViewControllerContextTransitioning>)transitionContext {
        UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
        UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
        UIView *containerView = [transitionContext containerView];
        CGRect toVCFrame = [transitionContext finalFrameForViewController:toVC];
        [containerView addSubview:toVC.view];
        [containerView sendSubviewToBack:toVC.view];
        //对tempView做动画,避免bug;
        UIView *tempView = [toVC.view snapshotViewAfterScreenUpdates:YES];
        tempView.frame = CGRectOffset(toVCFrame, 0, SCREEN_HEIGHT);
        [containerView addSubview:tempView];
        //增加阴影
        tempView.layer.shadowOffset = CGSizeMake(0, 1);
        tempView.layer.shadowColor = [UIColor lightGrayColor].CGColor;
        tempView.layer.shadowOpacity = 0.8;
        [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
            tempView.frame = toVCFrame;
        } completion:^(BOOL finished) {
            [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
            [tempView removeFromSuperview];
            [containerView bringSubviewToFront:toVC.view];
        }];
    }
    

           以上代码是自定义push从下到上显示,该方法包含一个transitionContext对象,我们来看看该对象的几个重要属性

           -containerView 包含上下文的容器,动画在该容器中进行

           -viewControllerForKey  获取fromVC/toVC

           -finalFrameForViewController 获取fromVC/toVC的最终展示frame

           一般的做法是根据转场类型push/pop做相应处理,通常是frame,alpha的的简单变化,也可以做复杂点的三维变化。

           如果是push动画,A->B,fromVC是A,toVC是B;pop B,fromVC是B,toVC是A。每次变换container中必须添加toVC.view,截取该视图,对截取的视图做相应动画,动画结束后,恢复原始状态即可。

      2.present/dismiss动画,默认的是从下到上呈现,以及从上到下消失

          自定义实现步骤:

          1.自定义的页面需要声明UIViewControllerTransitionningDelegate,并设置modelPresentationStyle为custom,同事还需实现相关的代理方法

    @interface XWPresentedOneController ()<UIViewControllerTransitioningDelegate>
    @property (nonatomic, strong) XWInteractiveTransition *interactiveDismiss;
    @property (nonatomic, strong) XWInteractiveTransition *interactivePush;
    @end
    
    @implementation XWPresentedOneController
    
    - (void)dealloc{
        NSLog(@"销毁了!!!!!");
    }
    
    - (instancetype)init
    {
        self = [super init];
        if (self) {
            self.transitioningDelegate = self;
            self.modalPresentationStyle = UIModalPresentationCustom;
        }
        return self;
    }
    
    - (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source{
        return [XWPresentOneTransition transitionWithTransitionType:XWPresentOneTransitionTypePresent];
    }
    
    - (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed{
        return [XWPresentOneTransition transitionWithTransitionType:XWPresentOneTransitionTypeDismiss];
    }
    
    - (id<UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id<UIViewControllerAnimatedTransitioning>)animator{
        return _interactiveDismiss.interation ? _interactiveDismiss : nil;
    }
    
    - (id<UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id<UIViewControllerAnimatedTransitioning>)animator{
        XWInteractiveTransition *interactivePresent = [_delegate interactiveTransitionForPresent];
        return interactivePresent.interation ? interactivePresent : nil;
    }
    
    @end
    

           UIViewControllerTransitionDelegate重要方法介绍

           - animationControllerForPresentedController:  present返回实现<UIViewControllerTransitioning>对象

           - animationControllerForDismissedController:    返回自定义的dimiss对象

           - interactionControllerForPresentation:     present返回百分比动画

           - interactionControllerForDismissal:       dismiss返回百分比动画

           百分比(交互式)动画,需定义UIPercentDrivenInteractiveTransition子类,绑定pan手势,根据手势的相应状态传递事件,本质上还是调用自定义实现的transition方法,因此没个transition完成动画的闭包中会有相应代码来回应交互式状态

    /开始动画吧,使用产生弹簧效果的动画API
        [UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0 usingSpringWithDamping:0.55 initialSpringVelocity:1.0 / 0.55 options:0 animations:^{
            //首先我们让vc2向上移动
            toVC.view.transform = CGAffineTransformMakeTranslation(0, -400);
            //然后让截图视图缩小一点即可
            tempView.transform = CGAffineTransformMakeScale(0.85, 0.85);
        } completion:^(BOOL finished) {
            //使用如下代码标记整个转场过程是否正常完成[transitionContext transitionWasCancelled]代表手势是否取消了,如果取消了就传NO表示转场失败,反之亦然,如果不是用手势的话直接传YES也是可以的,我们必须标记转场的状态,系统才知道处理转场后的操作,否者认为你一直还在,会出现无法交互的情况,切记
            [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
            //转场失败后的处理
            if ([transitionContext transitionWasCancelled]) {
                //失败后,我们要把vc1显示出来
                fromVC.view.hidden = NO;
                //然后移除截图视图,因为下次触发present会重新截图
                [tempView removeFromSuperview];
            }
        }];
    

    UIView的转场动画

      1.直接调用系统api  [UIView transitionWithView:duration:option:animation:^{}completion:^{}]

      - transitionView  需要转场到的视图

      - duration     动画时间

      - option      转场类型

      - aniamtion    动画块

      - completion    动画结束回调

    UIViewAnimationOptionTransitionNone           // default
    UIViewAnimationOptionTransitionFlipFromLeft   // 从左翻转
    UIViewAnimationOptionTransitionFlipFromRight  // 从右翻转
    UIViewAnimationOptionTransitionCurlUp         // 向上翻页
    UIViewAnimationOptionTransitionCurlDown       // 向下翻页
    UIViewAnimationOptionTransitionCrossDissolve  // 溶解
    UIViewAnimationOptionTransitionFlipFromTop    // 从上翻转
    UIViewAnimationOptionTransitionFlipFromBottom // 从下翻转
    

       2.使用CATransition 创建相应的animation,view.layer添加后直接在layer上渲染

       CATransition的基本属性,以下属性均可以使用kvc调用

       - type   转场类型

       - subtype   转场的子类型

       - duration  动画时间

       - timeFunction  动画加速度

    //    type  
        *1.kCATransitionMoveIn 新的视图把旧的视图掩盖
    
         *2.kCATransitionPush 旧的视图移走,新的视图移进来
    
         *3.kCATransitionFade 逐渐消失,相当于调整透明度,除了这没有方向,其他的都有
    
         *4.kCATransitionReveal 旧的视图移走,显示出新的视图
    
    //这类是API引入的,在苹果官网是不会承认的,所以不建议使用
    
          *1.animation.type = @"cube"; //立方体效果
    
         *2.animation.type = @"suckEffect";//犹如一块布被抽走
    
         *3. animation.type = @"oglFlip"; //上下翻转效果
    
         *4. animation.type = @"rippleEffect"; //滴水效果
    
         *5. animation.type = @"pageCurl"; //向左翻页
    
         *6.animation.type = @"pageUnCurl"; //向下翻页
    
    //    subtype
    
    kCATransitionFromBottom
    
    kCATransitionFromLeft
    
    kCATransitionFromRight
    
    kCATransitionFromTop
    
    //    timeFunction
    
    CA_EXTERN CAMediaTimingFunctionName const kCAMediaTimingFunctionLinear
    
    CA_EXTERN CAMediaTimingFunctionName const kCAMediaTimingFunctionEaseIn
    
    CA_EXTERN CAMediaTimingFunctionName const kCAMediaTimingFunctionEaseOut
    
    CA_EXTERN CAMediaTimingFunctionName const kCAMediaTimingFunctionEaseInEaseOut
    
    CA_EXTERN CAMediaTimingFunctionName const kCAMediaTimingFunctionDefault
    
  • 相关阅读:
    11种常用css样式之background学习
    11种常用css样式之开篇文本字体学习
    学习css常用基本层级伪类属性选择器
    学习了解CSS3发展方向和CSS样式与优先级
    常见CSS3选择器和文本字体样式汇总
    简单了解css3样式表写法和优先级
    4——PHP比较&&复制运算符
    虚基类
    string类中getline函数的应用
    string类应用举例
  • 原文地址:https://www.cnblogs.com/xiaoerheiwatu/p/9992939.html
Copyright © 2011-2022 走看看