IOS 核心动画CoreAnimation


CoreAnimation框架是苹果的核心技术之一,iOS以及MacOS之所以大受欢迎,其中一个重要的原因在于能够提供非常炫酷的动画效果,同时其对硬件的要求很低。

简介

Core Animation,中文翻译为核心动画,使用少量的代码就可以实现非常强大的功能。Core Animation的动画执行过程都是在后台操作的,因此不会阻塞主线程。
在这里插入图片描述
核心动画是直接作用于CALayer对象上的。当我们对一个UIView视图对象显示的内容进行旋转操作时,其本质是修改UIView的layer属性,对layer所展示的样式进行旋转操作后,再渲染到屏幕上。

CAAnimation类

CAAnimation类是一个抽象类,因此我们不会直接创建CAAnimation类的对象,而是使用其子类对象。其有3个子类,分别为:

  • CAPropertyAnimiation属性动画

  • CAAnimationGroup动画组

  • CATransition转场动画
    其中,CAPropertyAnimiation属性动画又包含两个子类,分别为:

  • CABasicAnimation基本动画

  • CAKeyframeAnimation关键帧动画
    在iOS9发布后,CABasicAnimation基本动画又添加了一个子类CASpringAnimation弹簧动画。
    在这里插入图片描述

CAMediaTiming协议常用属性

CAAnimation类遵守了CAMediaTiming协议,在该协议中定义了一些常用的与动画播放相关的属性。常用的包括如下几个。

beginTime:动画开始播放的时间,默认为0,即立即开始播放

@property CFTimeInterval beginTime;

duration:动画持续的时间,默认为0

@property CFTimeInterval duration;

speed:动画播放的速度,默认为1,数值越大播放的速度越快,例如,当取值为2时,以两倍速度播放动画

@property float speed;

repeatCount:动画重复播放的次数

@property float repeatCount;

repeatDuration:动画重复播放的时间间隔

@property CFTimeInterval repeatDuration;

fillMode:定义动画播放完毕后的动作,一共有4个可选动作,默认为:kCAFillModeRemoved,即恢复原样

@property(copy) NSString *fillMode;
CA_EXTERN NSString * const kCAFillModeForwards;
CA_EXTERN NSString * const kCAFillModeBackwards;
CA_EXTERN NSString * const kCAFillModeBoth;
CA_EXTERN NSString * const kCAFillModeRemoved;

CAAnimation类的代理协议CAAnimationDelegate

CAAnimationDelegate是CAAnimation类的代理协议,其中定义了与动画播放相关的一些方法,主要包括:

动画开始播放时调用的方法

- (void)animationDidStart:(CAAnimation *)anim;

动画停止播放时调用的方法,停止播放的原因有可能是动画播放完成,也有可能是人为控制动画停止播放

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;

动画实现步骤

当我们需要创建一个动画时,通常可以按照如下步骤进行:

实例化一个CAAnimation的子类对象,例如CABasicAnimation、CAKeyframeAnimation、CATransition等;
设置动画对象的动画属性;
添加动画对象到一个CALayer类的对象上,并播放动画。

举例:

我们通过一个简单的示例,介绍一下动画的实现步骤,该示例实现了对一个视图对象的layer进行平移,在平移的过程中播放动画。

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    //初始化CALayer对象,并添加到控制器view的layer上
    CALayer *subLayer = [CALayer layer];
    subLayer.frame = CGRectMake(140, 100, 100, 100);
    subLayer.backgroundColor = [UIColor yellowColor].CGColor;
    subLayer.borderColor = [UIColor redColor].CGColor;
    subLayer.borderWidth = 4.0;
    subLayer.cornerRadius = 2.0;
    [self.view.layer addSublayer:subLayer];
    //延时1秒后
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        //1-实例化CABasicAnimation对象
        CABasicAnimation *animation = [CABasicAnimation animation];
        //2-设置动画属性
        animation.keyPath = @"position";
        //锚点
        animation.toValue = [NSValue valueWithCGPoint:CGPointMake(290, 150)];
        animation.duration = 2.0;
        animation.repeatCount=3;
        //3-添加动画对象到一个CALayer类的对象上,播放动画
        [subLayer addAnimation:animation forKey:nil];
    });
}

CAPropertyAnimiation类

CAPropertyAnimiation属性动画类是CAAnimation类的子类,其也是一个抽象类,在实际开发过程中,我们需要使用其子类,包括:CABasicAnimation类、CAKeyFrameAnimation类。在iOS9中,CABasicAnimation类由引入了一个新的子类CASpringAnimation类。
CAPropertyAnimiation类,从其字面意义上理解其与属性Property相关,即修改Property从而把属性变化的过程通过动画展现出来。在CAPropertyAnimiation类中,通过keyPath属性来设置针对哪个属性变化展现动画。

@property(nullable, copy) NSString *keyPath;

常用的keyPath:

// 旋转
transform.rotation.x 围绕x轴翻转 参数:角度 angle2Radian(4)

transform.rotation.y 围绕y轴翻转 参数:同上

transform.rotation.z 围绕z轴翻转 参数:同上

transform.rotation 默认围绕z轴

// 缩放
transform.scale.x x方向缩放 参数:缩放比例 1.5

transform.scale.y y方向缩放 参数:同上

transform.scale.z z方向缩放 参数:同上

transform.scale 所有方向缩放 参数:同上

// 平移
transform.translation.x x方向移动 参数:x轴上的坐标 100

transform.translation.y x方向移动 参数:y轴上的坐标

transform.translation.z x方向移动 参数:z轴上的坐标

transform.translation 移动 参数:移动到的点 (100,100)

// 其他属性
opacity 透明度 参数:透明度 0.5

backgroundColor 背景颜色 参数:颜色 (id)[[UIColor redColor] CGColor]

cornerRadius 圆角 参数:圆角半径 5

borderWidth 边框宽度 参数:边框宽度 5

bounds 大小 参数:CGRect

contents 内容 参数:CGImage

contentsRect 可视内容 参数:CGRect 值是0~1之间的小数

position 锚点位置

shadowColor 阴影颜色

shadowOffset 阴影的偏移量

shadowOpacity 阴影的透明度

shadowRadius 阴影的圆角

CABasicAnimation

CABasicAnimation类是使用最简单的核心动画类,我们只需要指定keyPath,然后设置起始值(fromValue)和目标值(toValue),然后再把该动画对象添加到一个CALayer类的对象上,即可实现动画的播放。
keyPath的初始值,默认情况下为空。当不设置fromValue的值时,动画播放的初始值取自layer对象的keyPath指定属性的当前值

@property(nullable, strong) id fromValue;

keyPath的目标值,即变动后的值

@property(nullable, strong) id toValue;

乘数。当fromValue不为空时,目标值为fromValue 乘以 byValue;当fromValue为空时,目标值为layer对象的keyPath指定属性的当前值乘以byValue

@property(nullable, strong) id byValue;

举例

平移,动画完成后会自动回到原位置。

-(void)base{
    //初始化CALayer对象,并添加到控制器view的layer上
    CALayer *subLayer = [CALayer layer];
    subLayer.frame = CGRectMake(140, 100, 100, 100);
    subLayer.backgroundColor = [UIColor yellowColor].CGColor;
    subLayer.borderColor = [UIColor redColor].CGColor;
    subLayer.borderWidth = 4.0;
    subLayer.cornerRadius = 2.0;
    [self.view.layer addSublayer:subLayer];
    //延时1秒后
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        //1-实例化CABasicAnimation对象
        CABasicAnimation *animation = [CABasicAnimation animation];
        //2-设置动画属性
        animation.keyPath = @"transform.translation.y";
        //锚点
        animation.toValue =@100;//平移的距离是100
        animation.duration = 2.0;
        animation.repeatCount=3;
        //3-添加动画对象到一个CALayer类的对象上,播放动画
        [subLayer addAnimation:animation forKey:nil];
    });
}

CASpringAnimation 弹簧动画

CASpringAnimation类是iOS9中新增的类,属于CABasicAnimation的子类,通过CASpringAnimation类可以创建具有弹簧效果的动画。
在CASpringAnimation类的定义中,包含了如下几个属性,我们可以通过设置这些属性来设置弹簧动画的展示效果。

mass:质量,影响图层运动时的惯性,mass取值越大,动画的时间越长

@property CGFloat mass;

stiffness:弹簧钢度系数,取值0~100,默认取值100

@property CGFloat stiffness;

damping:阻尼系数,影响反弹的次数,取值大于0,默认取值10

@property CGFloat damping;

初始速度,默认为0

@property CGFloat initialVelocity;

获取反弹时的停顿时间,只读属性

@property(readonly) CFTimeInterval settlingDuration;
//1-实例化对象
        CASpringAnimation *animation=[CASpringAnimation animation];
        //2-设置动画属性
        animation.keyPath = @"transform.translation.y";
        animation.fromValue=@0;
        animation.toValue=@200;
        animation.mass=100;
        animation.stiffness=50;
        animation.damping=5;
        animation.initialVelocity=0;
        
        animation.duration = 2.0;
        // animation.repeatCount=3;
        //3-添加动画对象到一个CALayer类的对象上,播放动画
        [subLayer addAnimation:animation forKey:nil];

CAKeyFrameAnimation

关键帧动画,可以在一个values数组中设置针对某个keyPath的多个变化值,从而设计出一个相对复杂的动画播放效果,例如,我们可以设置一个CALayer对象在多个点之间来回移动,或者可以设置多个平移的值。
CAKeyframeAnimation类与CABasicAnimation的区别是:CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个values数组保存多个数值,从而可以实现keyPath指定属性的复杂变化。在values中保存的每个元素都称为一个keyframe,CABasicAnimation可看做是只有2个关键帧的CAKeyframeAnimation。

@property(nullable, copy) NSArray *values;

注意:保存在values数组中的对象为NSValue类型的对象

另外,我们还可以设计layer的动画运行轨迹path,这里需要用到贝塞尔路径(UIBezierPath),还需要注意的是我们需要把UIBezierPath对象转成CGPathRef类型的对象。

@property(nullable) CGPathRef path;

举例

沿y轴,向下移动0,移动100,回到0,向上移动50
value的值表示改变多少;

-(void)keyFrame{
    //初始化CALayer对象,并添加到控制器view的layer上
    CALayer *subLayer = [CALayer layer];
    subLayer.frame = CGRectMake(140, 100, 100, 100);
    subLayer.backgroundColor = [UIColor yellowColor].CGColor;
    subLayer.borderColor = [UIColor redColor].CGColor;
    subLayer.borderWidth = 4.0;
    subLayer.cornerRadius = 2.0;
    [self.view.layer addSublayer:subLayer];
    //延时1秒后
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        //1-实例化对象
        CAKeyframeAnimation *animation=[CAKeyframeAnimation animation];
        //2-设置动画属性
        animation.keyPath = @"transform.translation.y";
        animation.values=@[@0,@100,@0,@-50];
        animation.duration = 2.0;
        // animation.repeatCount=3;
        //3-添加动画对象到一个CALayer类的对象上,播放动画
        [subLayer addAnimation:animation forKey:nil];
    });
}

CAAnimationGroup动画组

CAAnimationGroup动画组,顾名思义就是可以创建一组动画对象,在动画播放时,图层可以同时播放多种动画的叠加效果,例如,我们可以在图层平移过程中同时修改图层的透明度。通过CAAnimationGroup类的对象,我们可以实现复杂动画的播放效果。

-(void)group{
    //初始化CALayer对象,并添加到控制器view的layer上
    CALayer *subLayer = [CALayer layer];
    subLayer.frame = CGRectMake(140, 100, 100, 100);
    subLayer.backgroundColor = [UIColor yellowColor].CGColor;
    subLayer.borderColor = [UIColor redColor].CGColor;
    subLayer.borderWidth = 4.0;
    subLayer.cornerRadius = 2.0;
    [self.view.layer addSublayer:subLayer];
    //延时1秒后
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        //1-实例化对象
        CABasicAnimation *animation1=[CABasicAnimation animation];
        //2-设置动画属性
        animation1.keyPath = @"transform.translation.y";
        animation1.fromValue=@0;
        animation1.toValue=@200;
        
        CABasicAnimation *animation2=[CABasicAnimation animation];
        animation2.keyPath=@"opacity";
        animation2.fromValue=@1;
        animation2.toValue=@0.1;
        
        CAAnimationGroup *group=[CAAnimationGroup animation];
        group.animations=@[animation1,animation2];
        group.duration=2.0;
        //添加动画组到layer上
        [subLayer addAnimation:group forKey:nil];
        
    });
}

CATransition转场动画

CATransition转场动画可以定义图层的显示内容在切换的时候的动画效果,例如,在导航控制器使用过程中,子控制器的显示与退出效果就是通过CATransition转场动画实现的。另外,在苹果KeyNote中,当我们切换幻灯片时,也会体现切换的效果。
通过设置CATransition类中的属性,我们可以定制转场动画的效果,常用的属性主要包括:

type:动画的类型。常用的有4种:fade(渐变)、moveIn(移入)、push(推入)、reveal(移出),默认为fade(渐变)

@property(copy) NSString *type;

subType:动画的子类型,可以指定动画播放时开始的方位或方向,有4中方式:fromLeft(从左开始)、fromRight(从右开始)、fromTop(从上开始) 、fromBottom(从下开始)

@property(nullable, copy) NSString *subtype;

转场动画启动时以及结束时的进度百分比,取值为0~1,通过设置这两个属性,我们可以实现动画从中间某个状态开始播放,或者在中间某个状态提前结束。

@property float startProgress;
@property float endProgress;

例子

#import "ViewController.h"

@interface ViewController ()
@property (nonatomic,strong)UIImageView *imageView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.imageView];
}
- (UIImageView *)imageView{
    if (_imageView==nil) {
        _imageView=[[UIImageView alloc]initWithFrame:CGRectMake(140, 100, 100, 100)];
        UIImage *image=[UIImage imageNamed:@"1"];
        [_imageView setImage:image];
    }
    return _imageView;
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    self.imageView.image=[UIImage imageNamed:@"2"];
    CATransition *animation=[CATransition animation];
  //  animation.type=kCATransitionFade;
  //如果输入的type的值没有定义,就会使用默认的fade,渐变
    animation.type=@"push";
    animation.subtype=kCATransitionFromRight;
    animation.duration=5;
    [self.imageView.layer addAnimation:animation forKey:nil];
}

代码

https://github.com/ShaeZhuJiu/CoreAnimation_Base.git

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值