网络中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. Python高级笔记(八)with、上下文管理器

    1. 上下文管理器 __enter__()方法返回资源对象,__exit__()方法处理一些清除资源 如:系统资源:文件.数据库链接.Socket等这些资源执行完业务逻辑之后,必须要关闭资源 #!/u ...

  2. springboot 项目基本目录包结构

    1.基本目录结构 controller service impl mapper utils domain config interceoter(拦截器) dto

  3. PLSQL集合类型的使用总结

    PLSQL集合类型的使用总结 在pl sql 中,集合(collection) 是一组有序的元素组成的对象,这些元素的类型必须一致. pl sql 将collection 分成3 类,分别为Assoc ...

  4. angular2 select 联动

    界面操作触发大分类id改变,根据id获取二级分类的数据进行绑定显示. html: <div style="overflow: hidden;float: left;padding-le ...

  5. CSS3动画框架 Animate.css

    CSS3的动画应用越来越多了,Animate.css一个从名字上就知道干什么的动画框架. github上的访问地址:http://daneden.github.io/animate.css/ 使用方法 ...

  6. iOS-UIPasteboard的使用

    剪贴板的使用以及自定义剪贴板. 系统剪贴板的直接调用 其实整个过程非常的简单,我就用我写的一个自定义UILable来说明调用系统剪贴板. 首先,因为苹果只放出来了 UITextView,UITextF ...

  7. 高级UI-事件传递

    事件传递在Android中有着举足轻重的作用,那么事件的传递在Android中又是怎么样实现的呢,在这里我们将进一步探讨Android的事件传递机制 从一个例子入手 首先是一个简单的onTouch和o ...

  8. python字符串/列表/元组/字典之间的相互转换(5)

    一.字符串str与列表list 1.字符串转列表 字符串转为列表list,可以使用str.split()方法,split方法是在字符串中对指定字符进行切片,并返回一个列表,示例代码如下: # !usr ...

  9. [转帖]JAVA虚拟机和安卓虚拟机的区别

    作者:天光链接:https://www.zhihu.com/question/20207106/answer/14654536来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出 ...

  10. Quartz.Net—DateBuilder

    定时框架中最重要的就是时间,我们也可以直接使用Cron这种事件格式.  使用其他的时间格式,就可以用DateBuilder快速的创建出需要的时间. 因为quartz是一个定时框架,所以对于操控时间  ...