CoreAnimation动画系列

Core Animation 动画的使用步骤

  1. 首先要先有CALayer(因为CoreAnimation是作用在CALayer上的)。
  2. 初始化一个CAAnimation对象,并设置一些动画相关属性。
  3. 通过调用CALayer的addAnimation:forKey:方法,增加CAAnimation对象到CALayer中,这样就能开始执行动画了
  4. 通过调用CALayer的removeAnimationForKey:
    方法可以停止CALayer中的动画

1. CALayer详解

CALayer的常用属性

cornerRadius       圆角
shadowColor       阴影颜色
shadowOffset      阴影偏移距离
shadowRadius     阴影模糊程度
shadowOpacity    阴影透明度
borderWidth        描边粗细
borderColor         描边颜色
anchorPoint         锚点
position            位置信息
transfrom           使CALayer产生3D空间的平移、缩放、旋转等变化。

layer的各种属性代码示例:

- (void)viewDidLoad { 
       [super viewDidLoad]; 
        // 设置图片为圆角 (self.qweImageView.frame.size.width / 2 变成圆形)  
        self.imageView.layer.cornerRadius =self.imageView.frame.size.width / 2; 
        // self.imageView.layer.masksToBounds = YES; 
        // 注意:光设置上边一句代码是实现不了效果的(下边的maskToBounds这个属性影响layer层的阴影效果) 
        // 设置layer的阴影颜色
        self.imageView.layer.shadowColor = [UIColor blueColor].CGColor;
         // 设置layer的透明度
        self.imageView.layer.shadowOpacity = 0.5f;
         // 设置阴影偏移量
        self.imageView.layer.shadowOffset = CGSizeMake(-30, 20);
        // 设置阴影的模糊度
        self.imageView.layer.shadowRadius = 1;
        // 创建View19 UIView *myView = [[UIView alloc] init];
        myView.backgroundColor = [UIColor redColor];
        // 设置frame
        myView.frame = CGRectMake(100, 500, 100, 100);
        // 设置视图圆角 (self.qweImageView.frame.size.width / 2 如果是方形视图变成圆形)
        myView.layer.cornerRadius = myView.frame.size.width / 2;
        // 设置阴影颜色
        myView.layer.shadowColor = [UIColor lightGrayColor].CGColor;
       // 设置阴影偏移量
       myView.layer.shadowOffset = CGSizeMake(10, 10);
       // 设置阴影的透明度
       myView.layer.shadowOpacity = 0.8f;
       // 设置阴影的模糊度
       myView.layer.shadowRadius = 1;
       // 添加到View上
        [self.view addSubview:myView];
       [self customLayer];
 }
 - (void)customLayer {
       // 创建一个layer对象
       CALayer *layer = [CALayer layer];
       // 设置对象的位置和大小
       layer.frame = CGRectMake(300, 280, 100, 100);
       // 设置背景颜色
       layer.backgroundColor = [UIColor redColor].CGColor;
       // 设置锚点
       // layer.anchorPoint = CGPointMake(0, 0);
       // 设置大小
       layer.position = CGPointMake(100, 100);
       // layer需要添加到layer层
        [self.view.layer addSublayer:layer];
 }
CALayer上动画的暂停和恢复
  • 暂停
-(void)pauseLayer:(CALayer*)layer { 
      CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil]; 
      // 让CALayer的时间停止走动 
      layer.speed = 0.0; 
      // 让CALayer的时间停留在pausedTime这个时刻
      layer.timeOffset = pausedTime; 
}
  • 恢复
-(void)resumeLayer:(CALayer*)layer { 
      CFTimeInterval pausedTime = layer.timeOffset; 
      // 1. 让CALayer的时间继续行走
      layer.speed = 1.0; 
      // 2. 取消上次记录的停留时刻 
      layer.timeOffset = 0.0; 
      // 3. 取消上次设置的时间
      layer.beginTime = 0.0; 
      // 4. 计算暂停的时间(这里也可以用CACurrentMediaTime()-pausedTime) 
      CFTimeInterval timeSincePause = [layer   convertTime:CACurrentMediaTime() fromLayer:nil] -   pausedTime; 
      // 5. 设置相对于父坐标系的开始时间(往后退timeSincePause) 
      layer.beginTime = timeSincePause; 
}

2. CAAnimation详解

CAAnimation类常用的可以分为四种

  • CABasicAnimation 通过设定起始点,终点,时间,动画会沿着你这设定点进行移动。可以看做特殊的CAKeyFrameAnimation
  • CAKeyframeAnimation Keyframe顾名思义就是关键点的frame,你可以通过设定CALayer的始点、中间关键点、终点的frame,时间,动画会沿你设定的轨迹进行移动
  • CAAnimationGroup Group也就是组合的意思,就是把对这个Layer的所有动画都组合起来。PS:一个layer设定了很多动画,他们都会同时执行,如何按顺序执行我到时候再讲。
  • CATransition 这个就是苹果帮开发者封装好的一些动画

** CAAnimation有很多派生类 **

CATransition 提供渐变效果:(推拉push效果,消退fade效果,揭开reveal效果)。
CAAnimationGroup 允许多个动画同时播放。
CABasicAnimation 提供了对单一动画的实现。
CAKeyframeAnimation 关键桢动画,可以定义行动路线。
CAConstraint 约束类,在布局管理器类中用它来设置属性。
CAConstraintLayoutManager 约束布局管理器,是用来将多个CALayer进行布局的.各个CALayer是通过名称来区分,而布局属性是通过CAConstraint来设置的。
CATransaction 事务类,可以对多个layer的属性同时进行修改.它分隐式事务,和显式事务。


CAAnimation的一些属性

  • duration 动画的持续时间
  • repeatCount 重复次数,无线循环可以设置HUGE_VALF或者MAXFLOAT
  • repeatDuration 重复时间
  • removedOnCompletion 默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。如果想让图层保持显示动画执行后的状态,那就设置为NO,不过还要设置fillMode为kCAFillModeForwards。
  • beginTime 可以用来设置动画延迟执行时间,若想延迟2s,就设置为CACurrentMediaTime()+2,CACurrentMediaTime()为图层的当前时间
  • timingFunction 速度控制函数,控制动画运行的节奏
  • delegate 动画代理
  • fillMode 决定当前对象在非active时间段的行为。(要想fillMode有效,最好设置removedOnCompletion = NO)
  • kCAFillModeRemoved 这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态
  • -- kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状态
  • -- kCAFillModeBackwards 在动画开始前,只需要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始。
  • -- kCAFillModeBoth 这个其实就是上面两个的合成.动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态
  • CAMediaTimingFunction 速度控制函数
  • kCAMediaTimingFunctionLinear(线性):匀速,给你一个相对静态的感觉
  • kCAMediaTimingFunctionEaseIn(渐进):动画缓慢进入,然后加速离开
  • kCAMediaTimingFunctionEaseOut(渐出):动画全速进入,然后减速的到达目的地
  • kCAMediaTimingFunctionEaseInEaseOut(渐进渐出):动画缓慢的进入,中间加速,然后减速的到达目的地。这个是默认的动画行为。

CAAnimation代理方法

  • 动画开始的时候调用
- (void)animationDidStart:(CAAnimation *)anim;
  • 动画停止的时候调用
    - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
    

** 其实比较重要的是有多个动画的时候如何在代理方法中区分不同的动画 **
方法一:

[self.imageView.layer addAnimation:animaGroup forKey:@"Animation"];
//动画开始时
- (void)animationDidStart:(CAAnimation *)anim{ 
  if ( [anim isEqual:[self.imageView.layer animationForKey:@"Animation"]]){ 
      NSLog(@"动画组执行了");
   }
}

把动画存储为一个属性然后再回调中比较,用来判定是哪个动画是不可行的。
方法二:

[positionAnima setValue:@"PositionAnima" forKey:@"AnimationKey"];
[transformAnima setValue:@"TransformAnima" forKey:@"AnimationKey"];
//动画结束时
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{ 
    if ([[anim valueForKey:@"AnimationKey"]isEqualToString:@"PositionAnima"]) { 
        NSLog(@"位置移动动画执行结束"); 
     } else if ([[anim valueForKey:@"AnimationKey"]isEqualToString:@"TransformAnima"])
     { 
            NSLog(@"旋转动画执行结束"); 
     }
}

所以,可以根据key中不同的值来进行区分不同的动画

3. CABasicAnimation 使用总结

CABasicAnimation提供了最基础的动画属性设置,是简单的keyframe动画性能。CABasicAnimation可以看做是一种CAKeyframeAnimation的简单动画,因为它只有头尾的关键帧(keyframe)。 我们可以创建一个CABasicAnimaiton的对象通过keyPath的方式。CABasicAnimation提供了fromValue、toValue、byValue的设置(插值)。它们三个属性定义了一个动画的轨迹,并且最少两个值不能为空。当设置了CABasicAnimation的起点与终点值后,中间的值都是通过插值方式计算出来的,插值计算是通过timingFunction来指定,timingFunction默认为空,使用liner(匀速运动)。例如,当我们设置了一个position的动画,设置了开始值PointA与结束值PointB,它们的运动先计算PointA与PointB的中间运动值PointCenter,而PointCenter是由timingFunction来指定值的,并且动画默认是直线匀速运动的。

属性说明

  • keyPath:要改变的属性名称(传字符串)
  • fromValue: KeyPath相应属性的初始值
  • toValue: keyPath相应属性的结束值

动画过程说明

  • 随着动画的进行,在长度为duration的持续时间内,keyPath相应属性的值从fromValue渐渐地变为toValue
  • keyPath内容是CALayer的可动画Animatable属性
  • 如果fillMode=kCAFillModeForwards
    同时removedOnComletion=NO,那么在动画执行完毕后,图层会保持显示动画执行后的状态。但在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变。

实例化

使用"animationWithKeyPath:"方法进行CABasicAnimation的实例化,并指定Layer的属性作为关键路径来注册。

// 指定position属性  
CABasicAnimation *animation =  [CABasicAnimation animationWithKeyPath:@"position"];  

设定动画

* duration        动画的时长
* repeatCount     重复的次数,不停重复设置为 HUGE_VALF
* repeatDuration  设置动画的时间,在该时间内动画一直执行,不计次数。
* beginTime       指定动画开始的时间。从开始延迟几秒的话,设置为【CACurrentMediaTime() + 秒数】 的方式
* timingFunction  设置动画的速度变化
* autoreverses    动画结束时是否执行逆动画
* fromValue       所改变属性的起始值
* toValue         所改变属性的结束时的值
* byValue         所改变属性相同起始值的改变量
* speed 改变动画的速度 可以直接设置动画上的speed属性,这样只有这个动画速度。//animation.speed = 2;
或者在layer上设置speed属性,这样在该视图上的所有动画都提速,该视图上的所有子视图上的动画也会提速。
 >  speed两点需注意的:
(1) 如果设置动画时间为4s,speed设置为2,则动画只需2s即可执行完。
(2)如果同时设置了动画的speed和layer 的speed,则实际的speed为两者相乘。
transformAnima.fromValue = @(M_PI_2);
transformAnima.toValue = @(M_PI);
transformAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transformAnima.autoreverses = YES;transformAnima.repeatCount = HUGE_VALF;
transformAnima.beginTime = CACurrentMediaTime() + 2;

防止动画结束后回到初始状态

只需设置removedOnCompletion、fillMode两个属性就可以了。

transformAnima.removedOnCompletion = NO;
transformAnima.fillMode = kCAFillModeForwards;

添加动画

[self.imageView.layer addAnimation:transformAnima forKey:@"A"];
------------------------------------
[positionAnima setValue:@"PositionAnima" forKey:@"AnimationKey"];

  • 一个 CABasicAniamtion 的实例对象只是一个数据模型,和他绑定到哪一个layer上是没有关系的
  • 方法addAnimation:forKey:是将 CABasicAniamtion 对象进行了 copy 操作的。所以在将其添加到一个layer上之后,我们还是将其再次添加到另一个layer上的。

fillMode属性

该属性定义了你的动画在开始和结束时的动作。默认值是 kCAFillModeRemoved。

  • kCAFillModeRemoved 设置为该值,动画将在设置的 beginTime 开始执行(如没有设置beginTime属性,则动画立即执行),动画执行完成后将会layer的改变恢复原状。
  • kCAFillModeForwards 设置为该值,动画即使之后layer的状态将保持在动画的最后一帧,而removedOnCompletion的默认属性值是 YES,所以为了使动画结束之后layer保持结束状态,应将removedOnCompletion设置为NO。
  • kCAFillModeBackwards 设置为该值,将会立即执行动画的第一帧,不论是否设置了 beginTime属性。观察发现,设置该值,刚开始视图不见,还不知道应用在哪里。
  • kCAFillModeBoth 该值是 kCAFillModeForwards 和 kCAFillModeBackwards的组合状态

timingFunction值得设定

(1)使用方法functionWithName:方法。
(2)使用方法functionWithControlPoints: : : :实现。

  • kCAMediaTimingFunctionLinear 传这个值,在整个动画时间内动画都是以一个相同的速度来改变。也就是匀速运动。
  • kCAMediaTimingFunctionEaseIn 使用该值,动画开始时会较慢,之后动画会加速。
  • kCAMediaTimingFunctionEaseOut 使用该值,动画在开始时会较快,之后动画速度减慢。
  • kCAMediaTimingFunctionEaseInEaseOut 使用该值,动画在开始和结束时速度较慢,中间时间段内速度较快。

解决有时视图会闪动一下的问题,我们可以将layer的属性值设置为我们的动画最后要达到的值,然后再给我们的视图添加layer动画。


一些常用的animationWithKeyPath值的总结

transform.scale   比例转化  @(0.8)
transform.scale.x   宽的比例    @(0.8)
transform.scale.y   高的比例    @(0.8)
transform.rotation.x    围绕x轴旋转  @(M_PI)
transform.rotation.y    围绕y轴旋转  @(M_PI)
transform.rotation.z    围绕z轴旋转  @(M_PI)
cornerRadius            圆角的设置    @(50)
opacity              透明度        @(0.7)
contentsRect.size.width 横向拉伸缩放  @(0.4)最好是0~1之间的
backgroundColor      背景颜色的变化    (id)[UIColor purpleColor].CGColor
bounds    大小,中心不变   [NSValue valueWithCGRect:CGRectMake(0, 0, 200, 200)];
position    位置(中心点的改变)  [NSValue valueWithCGPoint:CGPointMake(300, 300)];
contents    内容,比如UIImageView的图片 imageAnima.toValue = (id)[UIImage imageNamed:@"to"].CGImage;

4. CAKeyFrameAnimation详解

对 CAKeyFrameAnimation的使用与CABasicAnimation大同小异,有些属性是共通的。KeyFrame的意思是关键帧,所谓“关键”就是改变物体运动趋势的帧,在该点处物体将发生运动状态,比如矩形的四个角,抛物线的顶点等。因此,聪明的 你应该知道了,在下图中共有5个关键帧(图3中的ABCDE)。上个关键帧到当前关键帧之间的路径与当前关键帧相联系,比如AB->B,我们可 以对AB进行定义动画定义,而自定义要通过众多CAKeyFrameAnimation的属性达到目的。

1.png

(1)values属性
values属性指明整个动画过程中的关键帧点,例如上例中的A-E就是通过values指定的。需要注意的是,起点必须作为values的第一个值。
(2)path属性
作 用与values属性一样,同样是用于指定整个动画所经过的路径的。需要注意的是,values与path是互斥的,当values与path同时指定 时,path会覆盖values,即values属性将被忽略。例如上述例子等价于代码中values方式的path设置方式为:

CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, rectLayer.position.x - 15, rectLayer.position.y - 15);
CGPathAddLineToPoint(path, NULL, 320 - 15, rectLayer.frame.origin.y);
CGPathAddLineToPoint(path, NULL, 320 - 15, rectLayer.frame.origin.y + 100);
CGPathAddLineToPoint(path, NULL, 15, rectLayer.frame.origin.y + 100);
CGPathAddLineToPoint(path, NULL, 15, rectLayer.frame.origin.y);
rectRunAnimation.path = path;
CGPathRelease(path);

(3)keyTimes属性
该 属性是一个数组,用以指定每个子路径(AB,BC,CD)的时间。如果你没有显式地对keyTimes进行设置,则系统会默认每条子路径的时间 为:ti=duration/(5-1),即每条子路径的duration相等,都为duration的1\4。当然,我们也可以传个数组让物体快慢结 合。例如,你可以传入{0.0, 0.1,0.6,0.7,1.0},其中首尾必须分别是0和1,因此tAB=0.1-0, tCB=0.6-0.1, tDC=0.7-0.6, tED=1-0.7.....
(4)timeFunctions属性
用过UIKit层动画的同学应该对这个属性不陌生,这个属性用以指定时间函数,类似于运动的加速度,有以下几种类型。上例子的AB段就是用了淡入淡出效果。记住,这是一个数组,你有几个子路径就应该传入几个元素

5.CAAnimationGroup详解

CAAnimation的子类,可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行

属性解析:

animations:用来保存一组动画对象的NSArray默认情况下,一组动画对象是同时运行的,也可以通过设置动画对象的beginTime属性来更改动画的开始时间

代码实例

6. CATransition详解

CATransition * transition = [CATransition animation]; transition.duration = 1.0;//动画间隔 
transition.type = kCATransitionMoveIn;//主要种类,决定动画效果 
transition.startProgress = 0.0;//开始 transition.endProgress = 1.0;//结束 
transition.subtype = kCATransitionFromRight;//次要种类,决定动画方向 
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];//时间函数
[self.imageview.layer addAnimation:transition forKey:@"ToNext"]; 
self.imageview.image = nextImage;

type (动画类型)

  • 公开API
fade          淡出效果             kCATransitionFade
movein        新视图移动到旧视图上   kCATransitionMoveIn
push          新视图推出旧视图      kCATransitionPush
reveal        移开旧视图显示新视图   kCATransitionReveal  
  • 私有API (私有API只能通过字符串访)
cube            立方体翻转效果
oglFlip         翻转效果    
suckEffect       收缩效果   
rippleEffect       水滴波纹效果   
pageCurl           向上翻页效果   
pageUnCurl       向下翻页效果 
cameralIrisHollowOpen   摄像头打开效果 
cameraIrisHollowClose   摄像头关闭效果

subtype (动画子类)

kCATransitionFromRight  从右侧转场
kCATransitionFromLeft    从左侧转场
kCATransitionFromTop      从顶部转场
kCATransitionFromBottom   从底部转场
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥ios动画全貌。在这里你可以看...
    每天刷两次牙阅读 8,460评论 6 30
  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌。在这里你可以看...
    F麦子阅读 5,091评论 5 13
  • Core Animation Core Animation,中文翻译为核心动画,它是一组非常强大的动画处理API,...
    45b645c5912e阅读 3,012评论 0 21
  • 在iOS实际开发中常用的动画无非是以下四种:UIView动画,核心动画,帧动画,自定义转场动画。 1.UIView...
    请叫我周小帅阅读 3,076评论 1 23
  • 一.CoreAnimation介绍 CoreAnimation是一套图像渲染和动画基础框架,其在iOS和OSX平台...
    AlexCorleone阅读 964评论 0 15