网络中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. EXCEL导入配置开发

    1.登录infor 企业级 选择 配置 EXCEL导入配置 2.新增配置(设置模板名.说明.存储过程名称.应用仓库) 后保存 3.将excel模板放到服务器 路径:/opt/infor/sce/wil ...

  2. Linux的桌面虚拟化技术KVM(五)——virsh常用命令

    Linux的桌面虚拟化技术KVM(一)——新建KVM虚拟机 Linux的桌面虚拟化技术KVM(二)——远程桌面管理 Linux的桌面虚拟化技术KVM(三)——KVM虚拟机克隆和快照 Linux的桌面虚 ...

  3. HTTPS小结 、TSL、SSL

    https://segmentfault.com/a/1190000009020635

  4. LODOP粒度TableRowThickNess合并行测试

    之前的博文:LODOP打印table不切行TableRowThickNess. ,中是没有合并行等的表格,通过设置增大分页粒度,会找附近的表格线,然后根据表格线分页,避免了切行.如果有比较复杂的表格, ...

  5. 【Tools】PDF编辑软件-pdfelement 6.8 官网文件中文+破解版本

    试用了下,感觉还不错分享给大家. 有币的求赏,小弟下载缺币.没币的从附件下载. 赏币地址:https://download.csdn.net/download/qq_18187161/10744059 ...

  6. js 常用操作 -- 持续更新

    替换数组中某一元素: array.splice(2, 1, '哈哈'); // 2 表示指定数组中2下标元素,1表示要删除的项数,哈哈 是替换后的值 在数组中某元素之前增加元素: array.spli ...

  7. springboot集成kaptcha验证码

    在pom.xml引入依赖 <!-- 验证码 --> <!-- https://mvnrepository.com/artifact/com.github.penggle/kaptch ...

  8. (三)shiro的认证

    文章目录 认证思路 自定义用于登录检验的Realm的思路 代码实现 后记 认证思路 调用 SecurityUtils.getSubject() 方法,获取当前的 Subject 对象 : 调用 Sub ...

  9. 通俗理解TCP的三次握手

    三次握手流程的本质,可以这么理解:TCP的三次握手其实是双方各一次握手,各一次确认,只是其中一次握手和确认合并在一起. 当然也可以更通俗的去理解: "喂,你听得到吗?" " ...

  10. Python09之range函数(BIF内置函数)

    具体语法: range(起始值,结束值,步进值) range() 其属于内置函数,不需要导入其他模块即可使用,直接在Python的IDLE直接可以使用. list(range(0,10)) [0, 1 ...