核心动画(Core Animation)

Core Animation是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果

开发步骤 :
初始化一个动画对象 (CAAnimation) 并设置一些动画相关属性
添加动画对象到层 (CALayer) 中,开始执行动画

CALayer 中很多属性都可以通过 CAAnimation 实现动画效果,包括: opacity position transform bounds contents ( 可以在 API 文档中搜索: CALayer Animatable Properties )

通过调用 CALayer addAnimation:forKey 增加动画到层 (CALayer) ,这样就能触发动画了 。通过调用 removeAnimationForKey 可以 停止层中的动画
Core Animation 的动画执行过程都是在后台操作的,不会阻塞主线程

CAAnimation
所有动画对象的父类,负责控制动画的持续时间和速度,是个抽象类,不能直接使用,应该使用它具体的子类
属性解析: ( 红色代表来自 CAMediaTiming 协议的属性 )
duration :动画的持续时间
repeatCount :动画的重复次数
repeatDuration :动画的重复时间
removedOnCompletion :默认为 YES ,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。如果想让图层保持显示动画执行后的状态,那就设置为 NO ,不过还要设置 fillMode kCAFillModeForwards
fillMode :决定当前对象在非 active 时间段的行为 . 比如动画开始之前 , 动画结束之后
beginTime :可以用来设置动画延迟执行时间,若想延迟 2s ,就设置为 CACurrentMediaTime ()+2 CACurrentMediaTime () 为图层的当前时间
timingFunction :速度控制函数,控制动画运行的节奏
delegate :动画代理

CAAnimation继承结构


CAPropertyAnimation

CAAnimation的子类,也是个抽象类,要想创建动画对象,应该使用它的两个子类:CABasicAnimationCAKeyframeAnimation
属性解析:
keyPath:通过指定CALayer的一个属性名称为keyPath(NSString类型),并且对CALayer的这个属性的值进行修改,达到相应的动画效果。

CABasicAnimation

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

CAKeyframeAnimation

CApropertyAnimation 的子类,跟 CABasicAnimation 的区别是: CABasicAnimation 只能从一个数值 ( fromValue ) 变到另一个数值 ( toValue ) ,而 CAKeyframeAnimation 会使用一个 NSArray 保存这些数值
属性解析:
values :就是上述的 NSArray 对象。里面的元素称为 关键帧 ”( keyframe ) 。动画对象会在指定的时间 (duration) 内,依次显示 values 数组中的每一个关键帧
path :可以设置一个 CGPathRef \ CGMutablePathRef , 让层跟着路径移动。 path 只对 CALayer anchorPoint position 起作用。 如果你设置了 path ,那么 values 将被忽略
keyTimes :可以为对应的关键帧指定对应的时间点 , 其取值范围为 0 1.0,keyTimes 中的每一个时间值都对应 values 中的每一帧 . keyTimes 没有设置的时候 , 各个关键帧的时间是平分的
CABasicAnimation 可看做是最多只有 2 个关键帧的 CAKeyframeAnimation

CAAnimationGroup

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

CATransition

CAAnimation 的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。 iOS Mac OS X 转场 动画效果少一点
UINavigationController 就是通过 CATransition 实现了将控制器的视图推入屏幕的动画效果
属性解析 :
type :动画过渡类型
subtype :动画过渡方向
startProgress :动画起点 ( 在整体动画的百分比 )
endProgress :动画终点 ( 在整体动画的百分比 )

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

示例:

CABasicAnimation

大小的动画:

 // 通过核心动画实现在根层执行动画
    
    // 核心动画的使用步骤
    // 1、创建一个动画对象
    CABasicAnimation *animation = [CABasicAnimation animation];
#warning 核心动画只是一个假象,真是的大小是没有变化的
    // 设置图层的 “属性” 来决定 “动画的类型”
    // bounds:图层大小改变的动画
    animation.keyPath = @"bounds";
    
    // 设置bounds尺寸变化后的大小
    animation.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 200, 200)];
    
    // 使动画保存执行之后的状态
    animation.removedOnCompletion = NO;// 动画对象不要移除(YES:动画执行完后移除动画对象(默认))
    animation.fillMode = kCAFillModeForwards;// 保存当前的状态
    
    
    // 2、往控件的图层上添加动画(控件的图层是根图层)
    [self.imageView.layer addAnimation:animation forKey:nil];

位置的动画1:

 //1.创建一个动画对象
    CABasicAnimation *animation = [CABasicAnimation animation];
    
    //设置动画类型
    animation.keyPath = @"position";
    
    //动画执行的 "初始状态"
    //animation.fromValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
    
    //动画执行的 "最终状态"
    //animation.toValue = [NSValue valueWithCGPoint:CGPointMake(100, 250)];
    
    
    //每次动画执行的  "增加值"
    animation.byValue = [NSValue valueWithCGPoint:CGPointMake(10, 10)];
    
    //保存动画执行状态
    //解决方案2:使动画保存执行之后的状态,只要设置动画的两个属性
    animation.removedOnCompletion = NO;//动画对象不要移除
    animation.fillMode = kCAFillModeForwards;//保存当前的状态
    
    
    //2.往控件的图层添加动画
    [self.imageView.layer addAnimation:animation forKey:nil];
位置的动画2:

//1.创建一个动画对象
    CABasicAnimation *animation = [CABasicAnimation animation];
    
    //设置动画类型
    //animation.keyPath = @"transform.translation";
    animation.keyPath = @"transform.translation.x";

    //每次动画执行的  "增加值"
    //animation.byValue = [NSValue valueWithCGPoint:CGPointMake(10, 10)];
    //byValue的数据类型 由 keyPath 决定
    animation.byValue = @10;
   
    
    //保存动画执行状态
    //解决方案2:使动画保存执行之后的状态,只要设置动画的两个属性
    animation.removedOnCompletion = NO;//动画对象不要移除
    animation.fillMode = kCAFillModeForwards;//保存当前的状态
    
    
    //2.往控件的图层添加动画
    [self.imageView.layer addAnimation:animation forKey:nil];

旋转的动画:

//核心动画使用步骤
    //1.创建一个动画对象
    CABasicAnimation *animation = [CABasicAnimation animation];
    
    //设置动画类型
    animation.keyPath = @"transform.rotation.x";

    //每次动画执行的  "增加值"
    //byValue的数据类型 由 keyPath 决定
    animation.byValue = @(M_PI_4);
    
    
    //保存动画执行状态
    //解决方案2:使动画保存执行之后的状态,只要设置动画的两个属性
    animation.removedOnCompletion = NO;//动画对象不要移除
    animation.fillMode = kCAFillModeForwards;//保存当前的状态
    
    
    //2.往控件的图层添加动画
    [self.imageView.layer addAnimation:animation forKey:nil];

缩放的动画:

 //1.创建一个动画对象
    CABasicAnimation *animation = [CABasicAnimation animation];
    
    //设置动画类型 -》 keyPath设置图层的属性 bounds/position/transform。。。。
    animation.keyPath = @"transform.scale.x";
    
    // 设置动画的时间
    animation.duration = 3;

    //每次动画执行的  "增加值"
    //byValue的数据类型 由 keyPath 决定
    animation.byValue = @1.5;
    
    
    //保存动画执行状态
    //解决方案2:使动画保存执行之后的状态,只要设置动画的两个属性
    animation.removedOnCompletion = NO;//动画对象不要移除
    animation.fillMode = kCAFillModeForwards;//保存当前的状态
    
    
    //2.往控件的图层添加动画
    [self.imageView.layer addAnimation:animation forKey:nil];


CAKeyframeAnimation
帧动画:沿着指定路径执行的动画

//创建一个帧动画
    CAKeyframeAnimation *animaiton = [CAKeyframeAnimation animation];
    animaiton.keyPath = @"position";
    
    //设置动画执行的路径 指定四个点
    
    NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(50, 50)];
    NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(250, 50)];
    NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(250, 250)];
    NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(50, 250)];
    
    //数组第一个是 “开始状态” 最后一个是 "结束状态"
    animaiton.values = @[value1,value2,value3,value4,value1];
    
    //设置时间
    animaiton.duration = 5;
    
    //设置动画节奏
    //kCAMediaTimingFunctionEaseIn 先慢后快
    //kCAMediaTimingFunctionEaseOut 先快后慢
    //kCAMediaTimingFunctionLinear 线性匀速
    //kCAMediaTimingFunctionEaseInEaseOut 中间快两边慢
    animaiton.timingFunction =[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    
#warning 内部的path的优级大小values优先级
    //设置路径
    CGMutablePathRef path = CGPathCreateMutable();
    CGFloat screenW = [UIScreen mainScreen].bounds.size.width;
    CGPathAddEllipseInRect(path, NULL, CGRectMake(0, 0, screenW, screenW));
    
    animaiton.path = path;
    //c语言的数据类型 如果create/copy/retain创建要释放
    CFRelease(path);
    
    //添加动画
    [self.imgView.layer addAnimation:animaiton forKey:nil];

帧动画示例(图片抖动):

@interface ViewController ()
- (IBAction)start;
- (IBAction)stop;
@property (weak, nonatomic) IBOutlet UIImageView *imgIcon;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}


- (IBAction)start {
    
    //抖动图片 使用帧动画 设置 旋转的 路径
    
    CAKeyframeAnimation *rotationAni = [CAKeyframeAnimation animation];
    rotationAni.keyPath = @"transform.rotation";
    
    //计算好旋转的弧度
    CGFloat angle = M_PI_4;
    
    //设置 旋转的路径
    rotationAni.values = @[@(-angle),@(angle),@(-angle)];
    
    //设置动画执行的次数
    rotationAni.repeatCount = MAXFLOAT;
    
    [self.imgIcon.layer addAnimation:rotationAni forKey:@"shake"];
}

- (IBAction)stop {
    
    //通过key把动画移除,也就是把动画停止
    [self.imgIcon.layer removeAnimationForKey:@"shake"];
}

CATransition

转场动画:图片浏览器例子

#import "ViewController.h"

#define AnimationDuration 2

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imgView;
- (IBAction)tapView:(UITapGestureRecognizer *)sender;

@property(nonatomic,strong)NSMutableArray *imgs;

@property(nonatomic,assign)NSInteger currentImgIndex;//当前图片的索引

@end

@implementation ViewController


-(NSMutableArray *)imgs{
    if (!_imgs) {
        _imgs = [NSMutableArray array];
        for (NSInteger i = 1; i < 10; i++) {
            NSString *imgName = [NSString stringWithFormat:@"%ld.jpg",i];
            [_imgs addObject:imgName];
        }
    }
    
    return _imgs;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    NSLog(@"%@",self.imgs);
}

// 点击手势
- (IBAction)tapView:(UITapGestureRecognizer *)tap {
    
    // 实现判断图片的左半边还是右半边点击
    
    //获取触摸点
    CGPoint point = [tap locationInView:tap.view];
    NSLog(@"%@",NSStringFromCGPoint(point));
    
    if (point.x <= tap.view.bounds.size.width * 0.5) {
        NSLog(@"上一张");
        [self previous];
    }else{
        NSLog(@"下一张");
        [self next];
    }
}


-(void)previous{
    //判断当前图片是不是第一张
    if(self.currentImgIndex == 0){
        NSLog(@"已经是第一张");
        return;
    }
    
    //减索引 改图片
    self.currentImgIndex --;
    
    self.imgView.image = [UIImage imageNamed:self.imgs[self.currentImgIndex]];
    
    //转场动画
    CATransition *animation = [CATransition animation];
    animation.type = @"push";
    //默认就是fromLeft
    animation.subtype = @"fromLeft";
    
    animation.duration = AnimationDuration;
    
    [self.imgView.layer addAnimation:animation forKey:nil];


}

/**
 * 提示:转场的动画的类型(type)和子头型(subtype) 能用字符串常量就用字符常量
 */


/**
 *******************************************************
 type:动画类型(比如:滴水效果,翻转效果...)
 -------------------------------------------------------
 fade kCATransitionFade 交叉淡化过渡
 moveIn kCATransitionMoveIn 新视图移到旧视图上面
 push kCATransitionPush 新视图把旧视图推出去
 reveal kCATransitionReveal 将旧视图移开,显示下面的新视图
 pageCurl               向上翻一页
 pageUnCurl             向下翻一页
 rippleEffect             滴水效果
 suckEffect 收缩效果,如一块布被抽走
 cube                   立方体效果
 oglFlip              上下左右翻转效果
 rotate     旋转效果
 cameraIrisHollowClose 相机镜头关上效果(不支持过渡方向)
 cameraIrisHollowOpen 相机镜头打开效果(不支持过渡方向)
 
 *******************************************************
 subtype: 动画方向(比如说是从左边进入,还是从右边进入...)
 ------------------------------------------------------
 kCATransitionFromRight;
 kCATransitionFromLeft;
 kCATransitionFromTop;
 kCATransitionFromBottom;
 
 当 type 为@"rotate"(旋转)的时候,它也有几个对应的 subtype,分别为:
 90cw 逆时针旋转 90°
 90ccw 顺时针旋转 90°
 180cw 逆时针旋转 180°
 180ccw  顺时针旋转 180°
 **/
-(void)next{
    
    //判断当前图片是不是最后一张
    if (self.currentImgIndex == self.imgs.count - 1) {
        NSLog(@"已经是最后一张");
        return;
    }
    
    //加索引 改图片
    self.currentImgIndex ++;
    
    self.imgView.image = [UIImage imageNamed:self.imgs[self.currentImgIndex]];
    
    //切换图片的时候,使用转场动画
    CATransition *annimation = [CATransition animation];
    
    //设置转场动画的类型
    //`fade', 渐变
    //`moveIn', `push' and `reveal'
    annimation.type = @"rotate";
    
    //设置转卖动画的子类型
//    fromLeft', 动画由左边开始
//    `fromRight', 动画由右边开始
//`fromTop' and
//    * `fromBottom'
    annimation.subtype = @"90cw";
    
    annimation.duration = 3;
    
    [self.imgView.layer addAnimation:annimation forKey:nil];
    
    
    
}
@end

CAAnimationGroup
<span style="font-size:18px;"> // 有一张图片,同时可以有平移、旋转、缩放的效果
    // 实现这个效果 使用组动画[CAAnimationGroup]
    
    //组动画怎么使用
    //1.创建对象
    CAAnimationGroup *group = [CAAnimationGroup animation];
    
    //2.往里面添加多个动画
    //2.1平移动画
    CABasicAnimation *positionAni = [CABasicAnimation animation];
    positionAni.keyPath = @"position";
    positionAni.toValue = [NSValue valueWithCGPoint:CGPointMake(250, 250)];
    
    //2.2旋转效果
    CABasicAnimation *rotationAni = [CABasicAnimation animation];
    rotationAni.keyPath = @"transform.rotation";
    rotationAni.toValue = @(M_PI_2);
    
    
    //2.3缩放效果
    CABasicAnimation *scaleAni = [CABasicAnimation animation];
    scaleAni.keyPath = @"transform.scale";
    scaleAni.toValue = @(0.5);
    
    group.duration = 3;
    group.animations = @[positionAni,rotationAni,scaleAni];
    
    //3.把组动画添加到图层上
    [self.imgView.layer addAnimation:group forKey:nil];
</span>

















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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值