iOS动画——CoreAnimation
CoreAnimation
在我之前的UIKit动画里面简单的提了一句CoreAnimation动画,其实大家别看它类库名种有个animation,实际上animation在这个库中只占有很小的地位。
像我们经常用的边框、圆角、阴影、锚点等等这些属性都是有CA提供的。
在说CA动画前,我们先说一下CALayer这个类,CALayer可以叫做图层,UIView是视图。对别CALayer和UIView它们之间最大的差别在于CALayer是不处理交互的,比如点击事件等。
实际上UIView是CALayer的高层封装罢了,UIView的现实、绘图、动画等等都是封装的CALayer,在CALayer中有个重要的属性叫做affineTransform(放射变换),其实它和UIView中的transform是一摸一样的,返回的都是
CAAffineTransform。当你改变过一个view.transform属性或者view.layer.transform的时候需要恢复默认状态的话,记得先把他 们重置可以使用
view.transform = CGAffineTransformIdentity,或者view.layer.transform =CATransform3DIdentity,假设你一直不断的改变一个view.transform的属性,而每次改变之前没有重置的话,你会发现后来 的改变和你想要的发生变化了,不是你真正想要的结果。
现在大家对CALayer有了初步的认识,我们一起看看动画在CA中是如何使用的。
隐式动画
其实我们只要修改CALayer中和动画有关的属性,就算我们不写动画代码,在运行的时候也是会有动画效果的。这叫做隐式动画,也就是我们并没有明显的调用。
下面我们看个例子
@interface ViewController ()
{
CALayer *_viewLayer;
}
@end @implementation ViewController - (void)viewDidLoad
{
[super viewDidLoad]; _viewLayer = [CALayer layer];
_viewLayer.frame = CGRectMake(, , , );
[_viewLayer setBackgroundColor:[UIColor greenColor].CGColor];
_viewLayer.opacity = 0.25;
[self.view.layer addSublayer:_viewLayer]; // Do any additional setup after loading the view, typically from a nib.
} - (IBAction)click:(id)sender
{
CGAffineTransform moveTransforam = CGAffineTransformMakeTranslation(, );
[_viewLayer setAffineTransform:moveTransforam];
_viewLayer.opacity = ;
}
把这段代码输入,点击按钮,你就会发现view逐渐的变的不透明,并且位置也发生了改变。
显式动画
在显式动画中,不需要修改属性和调用动画执行方法,只需要通过CABasicAnimation逐个定义就行了,每个对象有持续时间、重复次数等属性,然后使用addAnimation:forkey:方法分别将每个动画用到图层的特定属性中。
能够做动画的图层属性有以下:
opacity;
transform.scale;
transform.scale.x;
transform.scale.y;
transform.rotation.z;
opacity;
margin;
zPosition;
backgroundColor;
cornerRadius;
bounds;
contents;
contentsRect;
frame;
hidden;
mask;
masksToBounds;
position;
shadowColor;
shadowOffset;
shadowOpacity;
shadowRadius;
下面我们看一个显式动画的例子:
CABasicAnimation *opAnim = [CABasicAnimation animationWithKeyPath:@"opacity"];
opAnim.duration = 3.0;
opAnim.fromValue = [NSNumber numberWithFloat:.];
opAnim.toValue = [NSNumber numberWithFloat:1.0];
opAnim.cumulative = NO;
opAnim.repeatCount = ;
opAnim.fillMode = kCAFillModeForwards;
opAnim.removedOnCompletion = NO;
[_viewLayer addAnimation:opAnim forKey:@"animateOpacity"]; CGAffineTransform moveTransform = CGAffineTransformMakeTranslation(, );
CABasicAnimation *moveAnim = [CABasicAnimation animationWithKeyPath:@"transform"];
moveAnim.duration = 6.0;
moveAnim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeAffineTransform(moveTransform)];
moveAnim.fillMode = kCAFillModeForwards;
moveAnim.removedOnCompletion = NO;
moveAnim.delegate = self;
moveAnim.repeatCount = ;
[_viewLayer addAnimation:moveAnim forKey:@"animateTransform"];
把click中的代码换成上面的代码,会发现视图慢慢变得不透明,过程中执行两次。
下面看一下CABasicAnimation属性有哪些作用:
属性 | 描述 |
duration | 动画持续时间 |
fromValue | 动画的属性起始值 |
toValue | 动画的属性目标值 |
cumulative | 是否保留上次动画的值 |
repeatCount | 重复次数 |
fillMode | 使用动画后不在返回原位置 |
removeOnCompletion | 动画完成后移除动画状态 |
delegate | 动画代理 |
这里简单说一下cumulative,上面例子如果cumulative设为YES的话,就不会执行第二次的opacity的变化了,因为保留了动画的状态。
fillMode和removeOnCompletion一起用使得动画结束后视图还在结束的位置,否则视图会回到原始位置。
不过这里说一下,虽然我们看到的值是已经变了,但是实际上原始值并不会因为做了动画而改变,只不过是affineTransform变了,如果要多次做affineTransform就要像上面说的,需要让它恢复初始值就不会出问题。
然后再来看看delegate,不过代理不是CABasicAnimation的,也不是它的父类CAPropertyAnimation的,而是它父类的父类CAAnimation的!
代理方法如下
- (void)animationDidStart:(CAAnimation *)anim;
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
一个是动画是在动画开始时的回调,另一个是在动画结束后的回调。
关键帧动画
关键帧动画其实也可以说又分两种,一种是帧动画一种是路径动画。
帧动画,不多说先看例子
CAKeyframeAnimation *opAnim = [CAKeyframeAnimation animationWithKeyPath:@"opacity"];
opAnim.duration = 6.0;
opAnim.values = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.25],[NSNumber numberWithFloat:0.75],[NSNumber numberWithFloat:1.0], nil];
opAnim.keyTimes = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],[NSNumber numberWithFloat:0.5],[NSNumber numberWithFloat:1.0], nil]; opAnim.fillMode = kCAFillModeForwards;
opAnim.removedOnCompletion = NO;
opAnim.delegate = self;
[_viewLayer addAnimation:opAnim forKey:@"animateOpacity"];
这里我们对透明度做动画,分别在values和keyTimes里面设置了到达某一时间应该到达的值,也就是通过这些值影响了在不同时间动画的状态不一样。大家应该还记得在之前的UIKit动画中,介绍过keyframe开始和持续时间的含义,它们都是总时间的百分比。
路径动画
路径动画动画其实可以说是特殊的帧动画,首先动画的对象属性是position,然后每一帧的速率都相同,用多线程的概念来讲大概就是串行执行动画的意思。
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, .f, .f);
CGPathAddLineToPoint(path, NULL, .f, .f);
CGPathAddLineToPoint(path, NULL, .f, .f);
CGPathAddLineToPoint(path, NULL, .f, .f);
CGPathAddLineToPoint(path, NULL, .f, .f);
CGPathCloseSubpath(path); CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
[anim setDuration:.f];
[anim setDelegate:self];
[anim setPath:path];
CFRelease(path);
path = nil;
[_viewLayer addAnimation:anim forKey:@"position"];
这里用CGMutablePathRef来产生路径上下文,其实CGMutablePathRef和绘图时的CGContextRef差不多。
下面设置不再是针对values和keyTimes了,而是设置它的path属性。
最后不要忘了释放CGMutablePathRef,因为它是CoreFoundation对象没有采用ARC所以要手动管理内存。
iOS动画——CoreAnimation的更多相关文章
- iOS开发CoreAnimation解读之一——初识CoreAnimation核心动画编程
iOS开发CoreAnimation解读之一——初识CoreAnimation核心动画编程 一.引言 二.初识CoreAnimation 三.锚点对几何属性的影响 四.Layer与View之间的关系 ...
- iOS 动画篇 (二) CAShapeLayer与CoreAnimation结合使用
接上一篇博客 iOS 动画篇(一) Core Animation CAShapeLayer是CALayer的一个子类,使用这个类能够很轻易实现曲线的动画. 先来一个折线动画效果: 示例代码: //1. ...
- iOS 动画基础
原文:http://www.cnblogs.com/lujianwenance/p/5733846.html 今天说一下有关动画的基础,希望能帮助到一些刚接触iOS动画或者刚开始学习iOS的同学, ...
- iOS开发CoreAnimation解读之三——几种常用Layer的使用解析
iOS开发CoreAnimation解读之三——几种常用Layer的使用解析 一.CAEmitterLayer 二.CAGradientLayer 三.CAReplicatorLayer 四.CASh ...
- iOS开发CoreAnimation解读之二——对CALayer的分析
iOS开发CoreAnimation解读之二——对CALayer的分析 一.UIView中的CALayer属性 1.Layer专门负责view的视图渲染 2.自定义view默认layer属性的类 二. ...
- 简析iOS动画原理及实现——Core Animation
本文转载至 http://www.tuicool.com/articles/e2qaYjA 原文 https://tech.imdada.cn/2016/06/21/ios-core-animati ...
- iOS 动画笔记 (一)
你也肯定喜欢炫酷的动画! 在APP中,动画就是一个点睛之笔!可以给用户增加一些独特的体验感,估计也有许多的和我一样的,看着那些觉得不错的动画,也就只能流口水的孩子,毕竟可能不知道从哪里下手去写!动画学 ...
- iOS动画——UIKit动画
iOS动画 iOS有很多动画技术,API主要分布在两个库中,一个是UIKit,另一个是CoreAnimation,先对UIKit动画做一下总结. UIKit动画 在UIKit中,很多API都可以看到a ...
- (转)iOS动画Core Animation
文章转载:http://blog.sina.com.cn/s/blog_7b9d64af0101b8nh.html 在iOS中动画实现技术主要是:Core Animation. Core Animat ...
随机推荐
- maven profile多环境自动切换配置,配置分离,排除文件
痛点: 在java开发的过程中,我们经常要面对各种各样的环境,比如开发环境,测试环境,正式环境,而这些环境对项目的需求也不相同. 在此之前,我们往往需要手动去修改相对应的配置文件然后打成war,才能部 ...
- yarn & vue-cli
yarn & vue-cli https://github.com/xgqfrms/ES6/issues/10 install https://yarnpkg.com/zh-Hans/docs ...
- 【GC分析】Java GC日志查看
Java中的GC有哪几种类型? 参数 描述 UseSerialGC 虚拟机运行在Client模式的默认值,打开此开关参数后, 使用Serial+Serial Old收集器组合进行垃圾收集. UsePa ...
- 1154 能量项链 2006年NOIP全国联赛提高组 codevs
1154 能量项链 2006年NOIP全国联赛提高组 codevs 题目描述 Description 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头 ...
- Hadoop2.0安装之非HA版
主要步骤跟Hadoop1.0(1.0安装地址)一致,主要在配置这块有更改 安装 下载地址:http://archive.apache.org/dist/hadoop/core/hadoop-2.6.5 ...
- plsql developer 64位版本
plsql developer 64位版本 http://www.3322.cc/soft/15748.html
- 11082 完全二叉树的种类 O(n) 卡特兰数
11082 完全二叉树的种类 时间限制:800MS 内存限制:1000K提交次数:0 通过次数:0 题型: 编程题 语言: G++;GCC;VC Description 构造n个(2<=n ...
- LeetCode 160. Intersection of Two Linked Lists (两个链表的交点)
Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...
- oc71--NSArray2
// // Person.h #import <Foundation/Foundation.h> @interface Person : NSObject - (void)say; - ( ...
- [JSOI 2012] 玄武密码
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=4327 [算法] AC自动机[代码] #include<bits/stdc++. ...