iOS Core Animation详解

一、CoreGraphics,QuartzCore, CoreAnimation区别

CoreGraphics(核心图形)

它是iOS的核心图形库,包含Quartz2D绘图API接口,常用的是point,size,rect等这些图形,都定义在这个框架中,类名以CG开头的都属于CoreGraphics框架,它提供的都是C语言函数接口,是可以在iOS和mac OS 通用的

QuartzCore

Quartz是位于Mac OS X的Drawin核心之上的绘图层

Core Animation

Core Animation,中文翻译为核心动画,它是一组非常强大的动画处理API,使用它能做出非常酷炫的动画效果。CoreAnimation是跨平台的,既可以支持IOS,也支持MAC OS。Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程。要注意的是,Core Animation是直接作用在CALayer上的,并非UIView。

image.png

二、Core Animation的继承结构

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

view是负责响应事件的,layer是负责显示的。


image.png

黄色的区块是常用的属性、方法或者需要遵守的协议,灰色是类名。
核心动画中所有类都遵守CAMediaTiming。

  • CAAnaimation是个抽象类,不具备动画效果,必须用它的子类CAAnimationGroup和CATransition)才有动画效果。
  • CAAnimationGroup(动画组),可以同时进行缩放,旋转。
  • CATransition(转场动画),界面之间跳转都可以用转场动画。
  • CAPropertyAnimation也是个抽象类,本身不具备动画效果,只有子类(CABasicAnimation和CAKeyframeAnimation)才有动画效果。
  • CABasicAnimation(基础动画),做一些简单效果。
  • CAKeyframeAnimation(帧动画),做一些连续的流畅的动画。

三、Core Animation使用步骤及相关属性

1、简单使用步骤
第一步:初始化一个CAAnimation对象,并设置一些动画相关属性。
第二步:通过调用CALayer的addAnimation:forKey:方法增加CAAnimation对象到CALayer中,这样就能开始执行动画了。
第三步:通过调用CALayer的removeAnimationForKey:方法可以停止CALayer中的动画。

2、常用属性

duration:持续时间,默认值是0.25秒

repeatCount:重复次数,无线循环可以设置HUGE_VALF或者CGFLOAT_MAX

repeatDuration:重复时间

removeOnCompletion: 默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到执行动画之前的状态。如果想要图层保持显示动画执行后的状态,那就设置为NO,同时设置fillMode为kCAFillModeForwards

fillMode:决定当前对象在非active时间段的行为,比如动画开始之前,动画结束之后

beginTime:可以用来设置动画延时执行,若想延迟2s,就设置为CACurrentMediaTIme() + 2

CACurrentMediaTIme():图层的当前时间

timingFunction:速度控制函数,控制动画运行节奏

delegate:动画代理

动画代理能够检测动画的执行和结束:

@interface NSObject (CAAnimationDelegate)
 - (void)animationDidStart:(CAAnimation *)anim;
 - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
@end

3、动画填充模式(fillMode)

kCAFillModeForwards:当动画结束后,layer会一直保持着动画最后的状态

kCAFillModeBackwards:在动画开始前,只需要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始

kCAFillModeBoth:这个其实就是上面两个合成,动画加入后,开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态

kCAFillModeRemoved:这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态

4、动画速度控制函数(timingFunction)

kCAMediaTimingFunctionLinear(线性):匀速,给你一个相对静态的感觉

kCAMediaTimingFunctionEaseIn(渐进):动画缓慢进入,然后加速离开

kCAMediaTimingFunctionEaseOut(渐出):动画全速进入,然后减速的到达目的地

kCAMediaTimingFunctionEaseInEaseOut(渐进渐出):动画缓慢的进入,中间加速,然后减速的到达目的地。这个是默认的动画行为。

5 、CALayer上动画的暂停和恢复
CALayer都是实现了CAMediaTiming协议(或者叫做接口)。所以layer的动画有一个属性speed。如果一个layer的速度变成0.0的时候,很显然这个动画就不再动了。设置layer的speed为0时,layer的动画暂停。speed属性设置为任意大于0的值时,动画恢复。

#pragma mark 暂停CALayer的动画
-(void)pauseLayer:(CALayer*)layer
{
    CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];

    // 让CALayer的时间停止走动
      layer.speed = 0.0;
    // 让CALayer的时间停留在pausedTime这个时刻
    layer.timeOffset = pausedTime;
}
#pragma mark 恢复CALayer的动画
-(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;
}

四、动画的调用方式

(1)UIView 代码块调用:

_demoView.frame = CGRectMake(0, 0, 50, 50);

UIView animateWithDuration:1.0f animations:^{
        _demoView.frame = CGRectMake(50, 50 50, 50);
    } completion:^(BOOL finished) {
        _demoView.frame = CGRectMake(100, 100, 50, 50);
    }];

(2)UIView [begin commit]模式

_demoView.frame = CGRectMake(0, 100, 50, 50);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0f];
_demoView.frame = CGRectMake(self.view.frame.size.width, self.view.frame.size.height/2, 50, 50);
[UIView commitAnimations];

(3)通过调用CALayer的addAnimation:forKey:

CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"position"];
anima.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, self.view.frame.size.height/2)];
anima.toValue = [NSValue valueWithCGPoint:CGPointMake(self.view.frame.size.width, self.view.frame.size.height/2)];
anima.duration = 1.0f;
[_demoView.layer addAnimation:anima forKey:@"positionAnimation"];

addanimation:forkey: 中的key可以设置为任意值

五、CAAnimation几个常用的子类

1、CABaseAnimation 基础动画
一些重要属性

fromValue : keyPath对应的初始值

toValue : keyPath对应的结束值

基础动画主要提供了对于CALayer对象中的可变属性进行简单动画的操作。比如:位移、透明度、缩放、旋转、背景色等等。

2、CAKeyframeAnimation 关键帧动画
Keyframe顾名思义就是关键点的frame,你可以通过设定CALayer的始点、中间关键点、终点的frame,时间,动画会沿你设定的轨迹进行移动 。
一些重要属性

path:这是一个 CGPathRef 对象,默认是空的,当我们创建好CAKeyframeAnimation的实例的时候,可以通过制定一个自己定义的path来让某一个物体按照这个路径进行动画。这个值默认是nil,当其被设定的时候,values 这个属性就被覆盖。

values:一个数组,提供了一组关键帧的值,当使用path的 时候 values的值自动被忽略。

对比基础动画跟关键帧动画,关键帧动画引入了动画占比时长的概念,这让我们能控制每个关键帧动画的占用比例而不是传入一个无意义的动画时长 —— 这让我们的代码更加难以理解。当然,除了动画占比之外,关键帧动画的options参数也让动画变得更加平滑,下面是关键帧特有的配置参数:

UIViewKeyframeAnimationOptionCalculationModeLinear // 连续运算模式,线性

UIViewKeyframeAnimationOptionCalculationModeDiscrete // 离散运算模式,只显示关键帧

UIViewKeyframeAnimationOptionCalculationModePaced // 均匀执行运算模式,线性

UIViewKeyframeAnimationOptionCalculationModeCubic // 平滑运算模式

UIViewKeyframeAnimationOptionCalculationModeCubicPaced // 平滑均匀运算模式

3、CAAnimationGroup 组合动画
Group也就是组合的意思,可以保存一组动画对象,将CAAnimationGroup对象加入图层后,组中所有动画对象可以同时并发运行。
其重要属性为:

animations:用来保存一组动画对象的NSArray

4、CATransition 过渡动画
CAAnimation的子类,用于做过渡动画或者转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。
重要属性:

type:动画过渡类型

subtype:动画过渡方向

startProgress:动画起点(在整体动画的百分比)

endProgress:动画终点(在整体动画的百分比)

有以下几种type:


image.png

有以下几种subtype:

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

推荐阅读更多精彩内容