关闭

核心动画(Core Animation)

标签: 核心动画Core Animation
392人阅读 评论(0) 收藏 举报
分类:

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

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

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

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

CAAnimation
所有动画对象的父类,负责控制动画的持续时间和速度,是个抽象类,不能直接使用,应该使用它具体的子类
属性解析:(红色代表来自CAMediaTiming协议的属性)
duration:动画的持续时间
repeatCount:动画的重复次数
repeatDuration:动画的重复时间
removedOnCompletion:默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。如果想让图层保持显示动画执行后的状态,那就设置为NO,不过还要设置fillModekCAFillModeForwards
fillMode:决定当前对象在非active时间段的行为.比如动画开始之前,动画结束之后
beginTime:可以用来设置动画延迟执行时间,若想延迟2s,就设置为CACurrentMediaTime()+2CACurrentMediaTime()为图层的当前时间
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只对CALayeranchorPointposition起作用。如果你设置了path,那么values将被忽略
keyTimes:可以为对应的关键帧指定对应的时间点,其取值范围为01.0,keyTimes中的每一个时间值都对应values中的每一帧.keyTimes没有设置的时候,各个关键帧的时间是平分的
CABasicAnimation可看做是最多只有2个关键帧的CAKeyframeAnimation

CAAnimationGroup

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

CATransition

CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。iOSMac 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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:11945次
    • 积分:610
    • 等级:
    • 排名:千里之外
    • 原创:51篇
    • 转载:4篇
    • 译文:0篇
    • 评论:0条
    文章分类