网络中Core Animation类的继承关系图

 
 
 

属性简介

@interface CAKeyframeAnimation : CAPropertyAnimation
/* 提供关键帧数据的数组,数组中的每一个值都对应一个关键帧。根据动画类型(keyPath)的不同 ,
值的类型不同*/
@property(nullable, copy) NSArray *values;
/*基于点的属性的路径,即动画属性类型为CGPoint。如: position、anchorPoint、transform.translation等
如果为此属性指定非空值,则会忽略values属性*/
@property(nullable) CGPathRef path;
/* keyTimes的值与values中的值一一对应指定关键帧在动画中的时间点,取值范围为[0,1]。当keyTimes没有设置的时候,
各个关键帧的时间是平分的*/
@property(nullable, copy) NSArray*keyTimes;
/*指定每个关键帧之间的动画缓冲效果,timingFunctions.count = keyTimes.count-1*/
@property(nullable, copy) NSArray*timingFunctions;
/*关键帧间插值计算模式*/
@property(copy) NSString *calculationMode;
/*针对cubic 计算模式的动画,这些属性提供对插值方案的控制。每个*关键帧都可以具有与之相关的
张力、连续性和偏差值,这些值的范围在[-1,1]内(这定义了Kochanek-*Bartels样条,见http://en.wikipedia.org/wiki/Kochanek-Bartels_spline)。 *tensionValues控制曲线的“紧密度”(正值更紧,负值更圆)。
*continuityValues控制段的连接方式(正值表示锐角,负值表示倒角)。
*biasValues定义曲线发生的位置(正值在控制点之前移动曲线,负值在控制点之后移动它)。 *每个数组中的第一个值定义第一个控制点的切线的行为,第二个值控*制第二个点的切线,依此类推。任何未指定的值都默认为零
*(如果未指定,则给出Catmull-Rom样条曲线)。
*/
@property(nullable, copy) NSArray*tensionValues;
@property(nullable, copy) NSArray*continuityValues;
@property(nullable, copy) NSArray *biasValues; /*定义沿路径动画的对象是否旋转以匹配路径切线*/
@property(nullable, copy) NSString *rotationMode; @end

关键帧动画其实通过一组动画类型的值(或者一个指定的路径)和这些值对应的时间节点以及各时间节点的过渡方式来控制显示的动画。关键帧动画可以通过path属性和values属性来设置动画的关键帧。

通过path设置动画

1.1 path只能控制CGPoint类型的动画属性。如position、anchorPoint、transform.translation等
1.2 创建路径时所有的MoveTo、LineTo、CurveTo等方法是定的点都组成了动画的关键帧。可以通过keyTimes属性赋值来控制关键帧的时间点,通过timingFunctions属性控制关键帧间的动画
来控制动画的显示。
1.3 path属性的优先级高于values属性优先级。当path被赋非空值时,values属性的值将被忽略。
1.4 贝塞尔曲线可视工具:
http://yisibl.github.io/cubic-bezier/#.99,.01,1,.49

- (void)setPathAnimation
{
CGMutablePathRef path = CGPathCreateMutable();
//第一个关键帧 -100,-100
CGPathMoveToPoint(path, NULL, -100, -100);
//第二个关键帧 100,-100
CGPathAddLineToPoint(path, NULL, 100, -100);
//第三个关键帧 100,100
CGPathAddLineToPoint(path, NULL, 100, 100);
//第四个关键帧 -100,100
CGPathAddLineToPoint(path, NULL, -100, 100);
//第五个关键帧 -100,-100
CGPathAddLineToPoint(path, NULL, -100, -100); CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
animation.keyPath = @"transform.translation";
animation.path = path;
animation.duration = 4;
animation.keyTimes = @[@(0),@(0.1),@(0.5),@(0.75),@(1)];
animation.timingFunctions = @[[CAMediaTimingFunction functionWithControlPoints:1 :0.5 :0.5 :0.5],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]];
//动画结束后保持动画最后的状态,两个属性需配合使用
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards; CGPathRelease(path);
[self.layer addAnimation:animation forKey:@""];
}

通过values设置动画

2.1 values指定了一组离散的关键帧,这些关键帧之间的需要通过插值来进行过渡。这些插值计算方式calculationMode设置。
2.2 网上看到有说calculationMode适用于anchorPoint 和 position等坐标点类型的属性,在查阅官方文档及代码测试,这种说法并不成立。calculationMode的插值计算方式同样适用于backgroundColor、opacity等非坐标点类型的动画属性

关键字 属性
kCAAnimationLinear calculationMode的默认值,关键帧之间直接直线相连进行插值计算
kCAAnimationDiscrete 离散的,就是不进行插值计算,所有关键帧直接逐个进行显示。values数组长度比keyTimes数组长度小1,每一个keyTime对表示当前关键帧的起始时间和下一关键帧的起始时间,在keyTime对的时间内,物体停留在当前关键帧指定的位置
kCAAnimationPaced 插入线性关键帧,动画以恒定速度运行。同时忽略keyTimes和timingFunctions设置
kCAAnimationCubic 对关键帧为进行圆滑曲线相连后插值计算,对于曲线的形状还可以通过tensionValues, continuityValues, biasValues来进行自定义调整,这里的数学原理是Kochanek–Bartels spline,这里的主要目的是使得运行的轨迹变得圆滑;
kCAAnimationCubicPaced 看这个名字就知道和kCAAnimationCubic有一定联系,其实就是在kCAAnimationCubic的基础上使得动画运行变得均匀,就是系统时间内运动的距离相同,此时keyTimes以及timingFunctions也是无效的。对于曲线的形状也可以使用tensionValues,continuityValues,biasValues来进行调整
- (void)setValuesAnimation
{
CGPoint center = self.view.center; CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
animation.keyPath = @"position";
animation.duration = 4;
animation.repeatCount = CGFLOAT_MAX;
animation.delegate = self; // 计算方式1: kCAAnimationLinear 直线相连进行插值计算
animation.calculationMode = kCAAnimationLinear;
animation.values = @[[NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)],
[NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y-100)],
[NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y+100)],
[NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y+100)],
[NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)]];
animation.keyTimes = @[@(0),@(0.25),@(0.5),@(0.75),@(1)];
animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]]; // 计算方式2: kCAAnimationDiscrete。 无插值计算values.count = keyTimes.count-1;
// animation.calculationMode = kCAAnimationDiscrete;
// animation.values = @[[NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)], //关键帧1开始时间0*duration=第0s
// [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y-100)], //关键帧2开始时间0.25*duration=第1s
// [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y+100)], //关键帧3开始时间0.5*duration=第2s
// [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y+100)]]; //关键帧4开始时间0.75*duration=第3s 在第4秒动画结束
// animation.keyTimes = @[@(0),@(0.25),@(0.5),@(0.75),@(1)]; // 计算方式3: kCAAnimationPaced。 关键帧间直线相连进行插值计算,动画以恒定速度运行,忽略keyTimes、timingFunctions;
// animation.calculationMode = kCAAnimationPaced;
// animation.values = @[[NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)],
// [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y-100)],
// [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y+100)],
// [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y+100)],
// [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)]]; // 计算方式4: kCAAnimationCubic。 关键帧间曲线相连进行插值计算
// animation.calculationMode = kCAAnimationCubic;
// animation.values = @[[NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)],
// [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y-100)],
// [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y+100)],
// [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y+100)],
// [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)]];
// //然而知道该如何精确操作
// animation.tensionValues = @[@(1),@(0),@(0),@(0),@(0)];
// animation.continuityValues = @[@(-1),@(1),@(-1),@(1),@(-1)];
// animation.biasValues= @[@(1),@(1),@(1),@(1),@(1)]; // 计算方式5: kCAAnimationCubic。关键帧间曲线相连进行插值计算,动画以恒定速度运行,忽略keyTimes、timingFunctions;
// animation.calculationMode = kCAAnimationCubicPaced;
// animation.values = @[[NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)],
// [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y-100)],
// [NSValue valueWithCGPoint:CGPointMake(center.x+100, center.y+100)],
// [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y+100)],
// [NSValue valueWithCGPoint:CGPointMake(center.x-100, center.y-100)]];
// animation.keyTimes = @[@(0),@(0.25),@(0.5),@(0.75),@(1)];
// animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
// [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn],
// [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut],
// [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]];
// //然而知道该如何精确操作
// animation.tensionValues = @[@(1),@(0),@(0),@(0),@(0)];
// animation.continuityValues = @[@(-1),@(1),@(-1),@(1),@(-1)];
// animation.biasValues= @[@(1),@(1),@(1),@(1),@(1)]; [self.layer addAnimation:animation forKey:@""]; if (!_displayLink) {
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
}

如有大神碰巧路过,发现问题请进行指正

demo地址:
https://gitee.com/dbmxl/KeyframeAnimation

参考文章:
http://www.iosxxx.com/blog/2015-11-01-coreanimationdong-hua-ru-men.html
https://www.jianshu.com/p/22333040616e

iOS动画:CAKeyframeAnimation的更多相关文章

  1. iOS:核心动画之关键帧动画CAKeyframeAnimation

    CAKeyframeAnimation——关键帧动画 关键帧动画,也是CAPropertyAnimation的子类,与CABasicAnimation的区别是: –CABasicAnimation只能 ...

  2. 解析 iOS 动画原理与实现

    这篇文章不会教大家如何实现一个具体的动画效果,我会从动画的本质出发,来说说 iOS 动画的原理与实现方式. 什么是动画 动画,顾名思义,就是能“动”的画.人的眼睛对图像有短暂的记忆效应,所以当眼睛看到 ...

  3. IOS动画隐式,显式,翻页

    //  ViewController.m //  IOS动画0817 // //  Created by 张艳锋 on 15/8/17. //  Copyright (c) 2015年 张艳锋. Al ...

  4. iOS动画原理

    1. iOS动画原理 本质:动画对象(这里是UIView)的状态,基于时间变化的反应 分类:可以分为显式动画(关键帧动画和逐帧动画)和隐式动画 关键帧和逐帧总结:关键帧动画的实现方式,只需要修改某个属 ...

  5. iOS动画实现总结

    在iOS中,动画实现方向有两种,一种是操作UIView的animation方法,另外一种就是核心动画,但到iOS7中,UIView又跟核心动画牵扯在一起. 方式一(利用核心动画添加动画) 核心动画的层 ...

  6. iOS 动画基础

    原文:http://www.cnblogs.com/lujianwenance/p/5733846.html   今天说一下有关动画的基础,希望能帮助到一些刚接触iOS动画或者刚开始学习iOS的同学, ...

  7. IOS动画总结

    IOS动画总结   一.基本方式:使用UIView类的UIViewAnimation扩展 + (void)beginAnimations:(NSString *)animationID context ...

  8. IOS 动画专题 --iOS核心动画

    iOS开发系列--让你的应用“动”起来 --iOS核心动画 概览 通过核心动画创建基础动画.关键帧动画.动画组.转场动画,如何通过UIView的装饰方法对这些动画操作进行简化等.在今天的文章里您可以看 ...

  9. iOS动画编程

    IOS中的动画总结来说有五种:UIView<block>,CAAnimation<CABasicAnimation,CATransition,CAKeyframeAnimation& ...

随机推荐

  1. webpack 相关文章

    webpack loader原理 由于webpack是基于Node的所以webpack只能识别.js文件,所以针对其他的文件就需要转译,这时候就需要用到我们的loader了. https://blog ...

  2. matplotlib常用操作2

    关于matplotlib学习还是强烈建议常去官方http://matplotlib.org/contents.html里查一查各种用法和toturial等. 下面是jupyter notebook代码 ...

  3. oracle根据sqlID查找相对应的sql语句

    转: 根据sqlID查找相对应的sql语句 2019-07-25 14:47:20 猛豪 阅读数 567更多 分类专栏: 数据库   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议 ...

  4. Angular常用命令:

    新建项目: ng new angualrdermo08 --skip-install 创建需要的组件: ng g component home

  5. SVL-VI SLAM

    3.4. Mappoints management and key frame process如果在步骤3.3中成功跟踪地图点,则缓存地图点以在下一帧中优先化.当完成当前帧的跟踪时,应该为下一帧更新帧 ...

  6. CharUtil

    package com.opslab.util; import java.io.UnsupportedEncodingException; /** * Various character and ch ...

  7. Shenzhen Wanze Technology Co., Ltd.隐私协议

    本隐私权政策详细说明了Shenzhen Wanze Technology Co., Ltd.团队(“我们”或“我们的”)通过我们的应用程序和网站收集的信息,以及我们将如何使用这些信息. 1.我们不会通 ...

  8. iOS textFiledView,label自适应高度

    CGSize constraintSize; constraintSize.width = 320; constraintSize.height = MAXFLOAT; CGSize sizeFram ...

  9. Golang中的Map(集合)

    Map 是一种无序的键值对的集合.Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值. Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它.不过,Map 是无 ...

  10. STM32驱动模数转换芯片ADS1120(PT100铂电阻测温度)第2篇

    1. 先看下原理图,原理图是电流从IDAC1流出,提供驱动,然后R(REF)这个电阻上的电压作为参考,读取AIN0和AIN1的电压,那么可以测量出来电阻值. 2. 上图是官方给出的参考,下图是我实际用 ...