iOS 动画相关知识

Core Animation,它是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍。在后台移动图层中的内容,  执行完毕后图层本身的位置并没有发生变化,所有的动画都继承自CAAnimation。iOS开发中实现动画的方式也不只是核心动画一种,也有UIView的几种动画。

一、核心动画

       Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程。要注意的是,Core Animation是直接作用在CALayer上的,并非UIView。所以,CALayer是核心动画的基础。

       创建动画的流程一般为:

              1、创建动画对象;2、设置动画属性;3、把动画对象添加到某个CALayer 对象上;4、需要停止动画:可以调用 remove 方法移除动画。

       动画类型有:

             1、 属性动画:设定某个属性的值,可以实现属性动画。2、基本动画(CABasicAnimation):设定某个属性从某个值到某个值,实现基本动画。

             3、关键帧动画(CAKeyframeAnimation):设定某个属性的值从某个值到某个值,再到某个值。按照关键值改变的顺序,实现动画。

             4、 组动画(CAAnimationGroup):把所有其他的动画添加到组里面,这样就可以按照添加的动画一次执行。

             5、 转场动画(CATransition):从一个场景转换到另一个场景,系统已经实现好了,不需要我们再去写,按照需求直接调用。

   1、CAAnimation

        所有动画对象的父类,负责控制动画的持续时间和速度,是个抽象类,不能直接使用,应该使用它具体的子类。

        属性有:1、duration(动画的持续时间,默认是0.25s) 2、repeatCount(动画重复次数) 3、repeatDuration(动画重复时间) 4、removedOnCompletion(默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。) 5、fillMode(决定当前对象在非active时间段的行为.比如动画开始之前,动画结束之后)6、beginTime(可以用来设置动画延迟执行时间)7、timingFunction(速度控制函数,控制动画运行的节奏)

       它还有一个隐式代理delegate,可以监听动画开始   -(void)animationDidStart:(CAAnimation *)anim ,监听动画结束   - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;

  2、CAPropertyAnimation(CAAnimation的子类)

       它本身也是一个抽象类,要想创建动画对象,应该使用它的两个子类:CABasicAnimation和CAKeyframeAnimation。

        重要属性keyPath:将CALayer的一个属性名称作为keyPath(NSString类型),并且对CALayer的这个属性的值进行修改,达到相应的动画效果。比如,指定@”position”为keyPath,就修改CALayer的position属性的值,以达到平移的动画效果。

      一、CABasicAnimation 基本动画

             有fromValue和toValue两个重要属性,随着动画的进行,在长度为duration的持续时间内,keyPath相应属性的值从fromValue渐渐地变为toValue,如果fillMode=kCAFillModeForwardsremovedOnComletion=NO,那么在动画执行完毕后,图层会保持显示动画执行后的状态。但在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变。比如,CALayer的position初始值为(0,0),CABasicAnimation的fromValue为(10,10),toValue为(100,100),虽然动画执行完毕后图层保持在(100,100)这个位置,实质上图层的position还是为(0,0)。

             例子:1、按路径移动(基本动画)

                           一、先创建动画对象,设置keypath  CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"];意思是沿着x轴平移

                           二、设置起始值和到达值 animation.fromValue= @(150);  animation.toValue = @(-150);  animation.duration=1;

                           三、添加到layer  [self.button.layer addAnimation:animation forKey:nil];

                       2、旋转(基本动画)

                          一、先创建动画对象 设置keypath CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];意思是沿着y轴旋转

                          二、设置属性值  NSNumber * num = @(M_PI*2); animation.toValue=num; animation.removedOnCompletion=NO;animation.fillMode=kCAFillModeForwards;

                                 animation.duration=3;animation.repeatCount=CGFLOAT_MAX;

                          三、添加到layer [self.button.layer addAnimation:animation forKey:nil];

        二、CAKeyframeAnimation 关键帧动画

              关键帧动画是多个值之间的变化实现动画的,有 values属性:关键帧数组,动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧;path:可以设置一个CGPathRef\CGMutablePathRef,让层跟着路径移动。path只对CALayer的anchorPoint和position起作用。如果你设置了path,那么values将被忽略;keyTimeshare:可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes中的每一个时间值都对应values中的每一帧.当keyTimes没有设置的时候,各个关键帧的时间是平分的。

            例子:1、按方形路径移动

                       一、创建动画对象,设置keypath CAKeyframeAnimation * animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];

                       二、设置values,NSValue * v1 = [NSValue valueWithCGPoint:CGPointMake(100, 200)];  NSValue * v2 = [NSValue valueWithCGPoint:CGPointMake(100, 400)];

                              NSValue * v2 = [NSValue valueWithCGPoint:CGPointMake(300, 400)];  NSValue * v2 = [NSValue valueWithCGPoint:CGPointMake(300, 200)];

                              NSValue * v2 = [NSValue valueWithCGPoint:CGPointMake(100, 200)];

                             animation.values=@[v1,v2,v3,v4,v5];

                             animation.duration=2;

                             animation.repeatCount=CGFLOAT_MAX;

                             animation.removedOnCompletion=NO;

                     三、添加到layer  [self.button.layer addAnimation:animation forKey:nil];

                      2、size变化

                            一、创建动画对象 CAKeyframeAnimation * animation = [CAKeyframeAnimation animationWithKeyPath:@"bounds.size"];

                            二、设置values NSValue * v0 = [NSValue valueWithCGSize:CGSizeMake(100, 100)]; NSValue * v1 = [NSValue valueWithCGSize:CGSizeMake(200, 200)];

                                   NSValue *v2 = [NSValue valueWithCGSize:CGSizeMake(100,100)];

                                   animation.values=@[v0,v1,v2];animation.duration=0.5;animation.repeatCount=CGFLOAT_MAX;

                                   animation.removedOnCompletion=NO; animation.fillMode=kCAFillModeForwards;

                            三、添加layer  [self.button.layer addAnimation:animation forKey:nil];

       基本动画和关键帧动画的区别在于CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值。CABasicAnimation可看做是最多只有2个关键帧的CAKeyframeAnimation。

      三、CAAnimationGroup 组动画

            可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行。有属性animations:用来保存一组动画对象的NSArray,默认情况下一组动画对象是同时运行的,也可以通过设置动画对象的beginTime属性来更改动画开始的时间

            例子:移动动画+抖动动画

                       一、创建动画对象

                             CAKeyframeAnimation * animation1 = [CAKeyframeAnimation animationWithKeyPath:@"position"];

                       二、设置属性,如上面的按方形移动

                       三、创建抖动动画对象,keypath为rotation.z

                       四、设置抖动动画对象的属性

                       五、创建组动画 CAAnimationGroup * animation = [CAAnimationGroup animation];  animation.animations=@[animation1,animation2];

                       六、将组动画添加到layer [self.button.layer addAnimation:animation forKey:nil];

        四、CATransition 转场动画

               用于做页面跳转时的转场动画,能够为层提供移出屏幕和移入屏幕的效果,这些动画的效果系统已经写好,我们只要配置一些属性即可。

               属性解析:1、type:动画过渡类型;2、subtype:动画过渡方向;3、startProgress:动画起点(在整体动画的百分比);4、endProgress:动画终点(在整体动画的百分比)

            例子:背景是界面上有一个UIImageview,添加了左滑和右滑手势,左右滑动实现UIImageview内容变化

                     1、使用CATransition实现转场(渐变消失)

                          一、创建动画  CATransition * animation = [CATransition animation];  

                          二、属性设置  animation.type = kCATransitionFade;(前一张消失)

                          三、添加到layer  [self.imageView.layer addAnimation:animation forKey:nil];

                     2、使用UIView(block)实现转场(向左拖:左右旋转+ 向右拖:上下翻页)

                          //如果向左滑动,向左旋转显示

        if (rec.direction==UISwipeGestureRecognizerDirectionLeft) {
            
            [UIView transitionWithView:self.imageView duration:1 options:UIViewAnimationOptionTransitionFlipFromRight animations:^{
                
               //block里面是控件的属性变化,这里和CATransition实现不同
                UIImage * image = [UIImage imageNamed:[NSString stringWithFormat:@"%ld",self.index]];
                self.imageView.image=image;
                
                
            } completion:nil];
        }
        
        //如果向右滑动,子页面向下推出
        else{
            [UIView transitionWithView:self.imageView duration:1 options:UIViewAnimationOptionTransitionCurlUp animations:^{
                
                UIImage * image = [UIImage imageNamed:[NSString stringWithFormat:@"%ld",self.index]];
                self.imageView.image=image;
                
            } completion:nil];
            
        }
    }

         3、使用CATransition实现转场(向左滑:向左退出 + 向右滑:向下推出)

        CATransition * animation = [CATransition animation];

        //如果向右滑动,子页面从左推出
        if (rec.direction == UISwipeGestureRecognizerDirectionRight) {
            animation.subtype = kCATransitionFromBottom;
            
        }
        //如果向右滑动,子页面从下推出
        
        else{
            animation.subtype = kCATransitionFromRight;
            
        }
        
        animation.type = kCATransitionPush;
        
        [self.imageView.layer addAnimation:animation forKey:nil];

      五、UIView block动画———(也可实现转场动画)

             UIKit框架直接将动画集成到UIView类中,当内部的一些属性发生改变时,UIView将为这些改变提供动画支持。将改变视图属性的代码写在block中,实现动画。有三种方式:

            1、+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion 其中,delay:动画延迟delay秒后开始,options:动画的节奏控制

            2、+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion 其中,view是需要进行转场动画的视图

            3、+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion  这个方法调用后相当于添加toview到父视图 [fromView.superview addSubview:toView]; ,把fromView从父视图中移除[fromView.superview removeFromSuperview];

     六、UIView  首尾式动画

            这是UIView的另一种实现动画方式。执行动画所需要的工作由UIView类自动完成,但仍要在希望执行动画时通知视图,为此需要将改变属性的代码放在[UIView beginAnimations:nil context:nil]和[UIView commitAnimations]之间,俗称首尾式动画。常见的方法有:

           1、设置动画代理对象,当动画开始或者结束时会发消息给代理对象  + (void)setAnimationDelegate:(id)delegate

           2、当动画即将开始时,执行delegate对象的selector,并且把beginAnimations:context:中传入的参数传进selector   + (void)setAnimationWillStartSelector:(SEL)selector

           3、当动画结束时,执行delegate对象的selector,并且把beginAnimations:context:中传入的参数传进selector   + (void)setAnimationDidStopSelector:(SEL)selector

           4、动画的持续时间,秒为单位  + (void)setAnimationDuration:(NSTimeInterval)duration

           5、动画延迟delay秒后再开始  + (void)setAnimationDelay:(NSTimeInterval)delay

           6、动画的开始时间,默认为now   + (void)setAnimationStartDate:(NSDate *)startDate

           7、动画的节奏控制  + (void)setAnimationCurve:(UIViewAnimationCurve)curve

           8、动画的重复次数 + (void)setAnimationRepeatCount:(float)repeatCount

           9、如果设置为YES,代表动画每次重复执行的效果会跟上一次相反  + (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses

          10、设置视图view的过渡效果, transition指定过渡类型, cache设置YES代表使用视图缓存,性能较好   + (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache

     七、UIImageView的帧动画

             UIImageView可以让一系列的图片在特定的时间内按顺序显示。

            属性解析:

             1、animationImages:要显示的图片(一个装着UIImage的NSArray)

             2、animationDuration:完整地显示一次animationImages中的所有图片所需的时间

             3、animationRepeatCount:动画的执行次数(默认为0,代表无限循环)

       八、UIActivityIndicatorView 转轮动画

             是一个旋转进度轮,可以用来告知用户有一个操作正在进行中,一般用initWithActivityIndicatorStyle初始化(之前的文章有做介绍)

              

 

posted @ 2019-06-05 11:13  小妮子的奋斗时代  阅读(187)  评论(0编辑  收藏  举报