• IOS 核心动画(Core Animation)


    • Core Animation,中文翻译为核心动画,它是一组非常强大的动画处理API,使用它 能做出非常炫丽的动画效果,而且往往是事半功倍。也就是说,使用少量的代码就 可以实现非常强大的功能。
    •  Core Animation可以用在Mac OS XiOS平台。
    • Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程。
    • 要注意的是,Core Animation是直接作用在CALayer上的,并非UIView

    Core Animation的使用步骤

     

    1.使用它需要先添加QuartzCore.framework框架和引入主头文件 <QuartzCore/QuartzCore.h>(iOS7不需要)

    2.初始化一个CAAnimation对象,并设置一些动画相关属性
    3.通过调用CALayeraddAnimation:forKey:方法增加CAAnimation对象
    CALayer中,这样就能开始执行动画了

    4.通过调用CALayerremoveAnimationForKey:方法可以停止CALayer 中的动画

     

    CAAnimation继承结构

     

    CAAnimation

    所有动画对象的父类,负责控制动画的持续时间和速度,是个抽象类,不能直接使用,应 该使用它具体的子类

    属性解析:(红色代表来自CAMediaTiming协议的属性) duration:动画的持续时间
    repeatCount:动画的重复次数
    repeatDuration:动画的重复时间

    removedOnCompletion:默认为YES,代表动画执行完毕后就从图层上移除,图形会恢 复到动画执行前的状态。如果想让图层保持显示动画执行后的状态,那就设置为NO,不过 还要设置fillModekCAFillModeForwards

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

    beginTime:可以用来设置动画延迟执行时间,若想延迟2s,就设置CACurrentMediaTime()+2, CACurrentMediaTime() 为图 层的当前时间

    timingFunction:速度控制函数,控制动画运行的节奏
    delegate:动画代理

    CAPropertyAnimation

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

    CABasicAnimation()

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

     基本动画

    #import <QuartzCore/QuartzCore.h>
    
    @interface NJViewController ()
    
    @property (nonatomic, strong) CALayer *myLayer;
    
    @end
    
    @implementation NJViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // 1.创建layer
        CALayer *myLayer = [CALayer layer];
        myLayer.bounds = CGRectMake(0, 0, 100, 100);
        
        myLayer.anchorPoint = CGPointZero;
        myLayer.position = CGPointMake(100, 100);
        myLayer.backgroundColor = [UIColor greenColor].CGColor;
        // 2.将自定义Layer添加到控制器的view的layer上
        [self.view.layer addSublayer:myLayer];
        
        self.myLayer = myLayer;
    
    }
    
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        // 1. 创建核心动画
        CABasicAnimation *anima = [CABasicAnimation animation] ;
        // 1.1设置动画类型
    //    anima.keyPath = @"transform.translation.x";
        anima.keyPath = @"transform.scale.y";
        
        // 1.2 设置动画执行完毕之后不删除动画
        anima.removedOnCompletion = NO;
        // 1.3 设置保存动画的最新状态
        anima.fillMode = kCAFillModeForwards;
        // 1.4设置动画时间
        anima.duration = 1;
        
        // 1.5如何动画
    //    anima.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0, 100, 1)];
    //    anima.toValue = @(100);
        anima.toValue = @(1.5);
     
        
        // 2.添加核心动画到Layer
        [self.myLayer addAnimation:anima forKey:nil];
    
    }
    
    - (void)test2
    {
        // 1. 创建核心动画
        CABasicAnimation *anima = [CABasicAnimation animation] ;
        // 1.1设置动画类型
        anima.keyPath = @"transform";
        
        
        // 1.2 设置动画执行完毕之后不删除动画
        anima.removedOnCompletion = NO;
        // 1.3 设置保存动画的最新状态
        anima.fillMode = kCAFillModeForwards;
        // 1.4设置动画时间
        anima.duration = 1;
        
        // 1.5修改动画
        anima.toValue =  [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_4, 0, 0, 1)];
        
        // 2.添加核心动画到Layer
        [self.myLayer addAnimation:anima forKey:nil];
    }
    
    
    - (void)test1
    {
        // 1. 创建核心动画
        CABasicAnimation *anima = [CABasicAnimation animation] ;
        // 1.1设置动画类型
        anima.keyPath = @"bounds";
        
        // 1.2 设置动画执行完毕之后不删除动画
        anima.removedOnCompletion = NO;
        // 1.3 设置保存动画的最新状态
        anima.fillMode = kCAFillModeForwards;
        // 1.4设置动画时间
        anima.duration = 1;
        
        // 1.5修改动画
        anima.toValue =[NSValue valueWithCGRect: CGRectMake(0, 0, 200, 200)];
        
        // 2.添加核心动画到Layer
        [self.myLayer addAnimation:anima forKey:nil];
    }
    
    - (void)test
    {
        // 1. 创建核心动画
        CABasicAnimation *anima = [CABasicAnimation animation] ;
        // 1.1告诉系统要执行什么样的动画
        anima.keyPath = @"position";
        // 设置通过动画将layer从哪
        //    anima.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];
        // 到哪(到指定的位置)
        anima.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 300)];
        //    在当前位置的基础上增加多少
        //    anima.byValue = [NSValue valueWithCGPoint:CGPointMake(0, 300)];
        
        // 设置动画时间
        anima.duration = 5;
        
        // 1.2 设置动画执行完毕之后不删除动画
        anima.removedOnCompletion = NO;
        // 1.3 设置保存动画的最新状态
        anima.fillMode = kCAFillModeForwards;
        
        // 2.添加核心动画到Layer
        [self.myLayer addAnimation:anima forKey:nil];
    }
    
    
    @end
    View Code

    CAKeyframeAnimation()

    ●  CApropertyAnimation的子类,跟CABasicAnimation的区别 是:CABasicAnimation只能从一个数值(fromValue)变到另一个数 值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值

    ●  属性解析:

    ●  values:就是上述的NSArray对象。里面的元素称为关键帧”(keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧

    ●  path:可以设置一个CGPathRefCGMutablePathRef,让层跟着路径移 动。path只对CALayeranchorPointposition起作用。如果你设置了 path,那么values将被忽略

    ●  keyTimes:可以为对应的关键帧指定对应的时间点,其取值范围为0 1.0,keyTimes中的每一个时间值都对应values中的每一帧.keyTimes没有 设置的时候,各个关键帧的时间是平分的

    ●  CABasicAnimation可看做是最多只有2个关键帧的CAKeyframeAnimation

    关键帧动画

    @interface NJViewController ()
    
    @property (weak, nonatomic) IBOutlet UIView *customView;
    - (IBAction)btnClick:(id)sender;
    @end
    
    @implementation NJViewController
    
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
    
        [self test];
    //    [self test1];
    }
    
    - (void)test1
    {
        // 1.创建核心动画
        CAKeyframeAnimation *keyAnima = [CAKeyframeAnimation animation];
        // 1.1告诉系统执行什么动画
        keyAnima.keyPath = @"position";
        
        CGMutablePathRef path = CGPathCreateMutable();
        CGPathAddEllipseInRect(path, NULL, CGRectMake(0, 100, 200, 200));
        
        keyAnima.path = path;
        CGPathRelease(path);
        
        // 1.2保存执行完之后的状态
        // 1.2.1执行完之后不删除动画
        keyAnima.removedOnCompletion = NO;
        // 1.2.2执行完之后保存最新的状态
        keyAnima.fillMode = kCAFillModeForwards;
        
        // 1.3设置动画时间
        keyAnima.duration = 2;
        // 2.观察动画什么时候开始执行, 以及什么时候执行完毕
        keyAnima.delegate = self;
        // 3.添加核心动画
        [self.customView.layer addAnimation:keyAnima forKey:@"abc"];
    }
    
    - (IBAction)btnClick:(id)sender {
        
        // 停止动画
        [self.customView.layer removeAnimationForKey:@"abc"];
    }
    
    
    - (void)test
    {
        // 1.创建核心动画
        CAKeyframeAnimation *keyAnima = [CAKeyframeAnimation animation];
        // 1.1告诉系统执行什么动画
        keyAnima.keyPath = @"position";
        //    NSValue *v1 = [NSValue valueWithCGPoint:CGPointMake(0, 100)];
        NSValue *v2 = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
        NSValue *v3 = [NSValue valueWithCGPoint:CGPointMake(100, 200)];
        NSValue *v4 = [NSValue valueWithCGPoint:CGPointMake(0, 200)];
        NSValue *v5 = [NSValue valueWithCGPoint:CGPointMake(0, 100)];
        
        keyAnima.values = @[v2, v3, v4, v5];
        
        //    keyAnima.keyTimes = @[@(0.5) ,@(0.5), @(0.5)];
        
        keyAnima.timingFunction =  [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        
        // 1.2保存执行完之后的状态
        // 1.2.1执行完之后不删除动画
        keyAnima.removedOnCompletion = NO;
        // 1.2.2执行完之后保存最新的状态
        keyAnima.fillMode = kCAFillModeForwards;
        
        // 1.3设置动画时间
        keyAnima.duration = 2;
        
        // 2.观察动画什么时候开始执行, 以及什么时候执行完毕
        keyAnima.delegate = self;
        
        
        // 2.添加核心动画
        [self.customView.layer addAnimation:keyAnima forKey:nil];
    }
    
    - (void)animationDidStart:(CAAnimation *)anim
    {
        NSLog(@"animationDidStart");
    }
    
    - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
    {
        NSLog(@"animationDidStop");
    }
    View Code

    图片抖动

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        // 1.创建核心动画
        CAKeyframeAnimation  *keyAnima = [CAKeyframeAnimation animation];
        keyAnima.keyPath = @"transform.rotation";
        // 度数 / 180 * M_PI
        keyAnima.values = @[@(-angle2Radian(4)), @(angle2Radian(4)), @(-angle2Radian(4))];
    
        keyAnima.removedOnCompletion = NO;
        keyAnima.fillMode = kCAFillModeForwards;
        keyAnima.duration = 0.1;
        
        // 设置动画重复的次数
        keyAnima.repeatCount = MAXFLOAT;
        
        // 2.添加核心动画
        [self.iconView.layer addAnimation:keyAnima forKey:nil];
    }
    View Code

    CAAnimationGroup

    • CAAnimation的子类,可以保存一组动画对象,将CAAnimationGroup对象加 入层后,组中所有动画对象可以同时并发运行
    • 属性解析:
    • animations:用来保存一组动画对象的NSArray
    • 默认情况下,一组动画对象是同时运行的,也可以通过设置动画对象的 beginTime属性来更改动画的开始时间
    @interface NJViewController ()
    @property (weak, nonatomic) IBOutlet UIView *iconView;
    
    @end
    
    @implementation NJViewController
    
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
       
        // 平移动画
        CABasicAnimation *a1 = [CABasicAnimation animation];
        a1.keyPath = @"transform.translation.y";
        a1.toValue = @(100);
        // 缩放动画
        CABasicAnimation *a2 = [CABasicAnimation animation];
        a2.keyPath = @"transform.scale";
        a2.toValue = @(0.0);
        // 旋转动画
        CABasicAnimation *a3 = [CABasicAnimation animation];
        a3.keyPath = @"transform.rotation";
        a3.toValue = @(M_PI_2);
        
        // 组动画
        CAAnimationGroup *groupAnima = [CAAnimationGroup animation];
        
        groupAnima.animations = @[a1, a2, a3];
        
        groupAnima.duration = 2;
        groupAnima.fillMode = kCAFillModeForwards;
        groupAnima.removedOnCompletion = NO;
        
        [self.iconView.layer addAnimation:groupAnima forKey:nil];
    }
    
    @end
    View Code

    CATransition

    CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的 动画效果。iOSMac OS X的转场动画效果少一点
    UINavigationController就是通过CATransition实现了将控制器的视图 推入屏幕的动画效果
    属性解析:
    type:动画过渡类型
    subtype:动画过渡方向
    startProgress:动画起点(在整体动画的百分比)
    endProgress:动画终点(在整体动画的百分比)
    #import "NJViewController.h"
    
    @interface NJViewController ()
    @property (weak, nonatomic) IBOutlet UIImageView *iconView;
    - (IBAction)nextBtnClick:(id)sender;
    - (IBAction)preBtnClick:(id)sender;
    
    @property (nonatomic, assign) int index;
    @end
    
    @implementation NJViewController
    
    // 下一张
    - (IBAction)nextBtnClick:(id)sender {
        self.index++;
        if (self.index >7) {
            self.index = 1;
        }
        
        NSString *imageName = [NSString stringWithFormat:@"%d.jpg", self.index];
        UIImage *newImage = [UIImage imageNamed:imageName];
        self.iconView.image = newImage;
        
        // 1.创建核心动画
        CATransition *ca = [CATransition animation];
        // 1.1动画过渡类型
        ca.type = @"cube";
        // 1.2动画过渡方向
        ca.subtype =  kCATransitionFromRight;
        // 1.3动画起点(在整体动画的百分比)
    //    ca.startProgress = 0.5;
        ca.endProgress = 0.5;
        
        
        // 动画时间
        ca.duration = 1;
        
        // 2.添加核心动画
        [self.iconView.layer addAnimation:ca forKey:nil];
    }
    
    // 上一张
    - (IBAction)preBtnClick:(id)sender {
        self.index--;
        if (self.index < 1) {
            self.index = 7;
        }
        NSString *imageName = [NSString stringWithFormat:@"%d.jpg", self.index];
        UIImage *newImage = [UIImage imageNamed:imageName];
        self.iconView.image = newImage;
        
        // 1.创建核心动画
        CATransition *ca = [CATransition animation];
        // 1.1告诉系统执行什么动画
        ca.type = @"cube";
        ca.subtype =  kCATransitionFromLeft;
        
        ca.duration = 1;
        
        // 2.添加核心动画
        [self.iconView.layer addAnimation:ca forKey:nil];
    
    }
    @end
    View Code
  • 相关阅读:
    webkit浏览器常见开发问题
    解密H264、AAC硬件解码的关键扩展数据处理
    Bitmap那些事之内存占用计算和加载注意事项
    android apk 防止反编译技术第三篇-加密
    linux设备驱动第五篇:驱动中的并发与竟态
    如何简单快速调试高大上的谷歌浏览器
    Asp.net Mvc对比Php的4大误解
    Python初学记录
    SQL循环+游标
    Nico Game Studio 3.地图纹理编辑 物体皮肤编辑
  • 原文地址:https://www.cnblogs.com/liuwj/p/6599522.html
Copyright © 2020-2023  润新知