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 从底部进入

你可能感兴趣的:(iOS Core Animation详解)