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(0, 0, 100, 100);
    [_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(180, 200);
    [_viewLayer setAffineTransform:moveTransforam];
    _viewLayer.opacity = 1;
}

把这段代码输入,点击按钮,你就会发现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:.25];
    opAnim.toValue = [NSNumber numberWithFloat:1.0];
    opAnim.cumulative = NO;
    opAnim.repeatCount = 2;
    opAnim.fillMode = kCAFillModeForwards;
    opAnim.removedOnCompletion = NO;
    [_viewLayer addAnimation:opAnim forKey:@"animateOpacity"];

    CGAffineTransform moveTransform = CGAffineTransformMakeTranslation(180, 200);
    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 = 2;
    [_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, 160.f, 100.f);
    CGPathAddLineToPoint(path, NULL, 100.f, 280.f);
    CGPathAddLineToPoint(path, NULL, 260.f, 170.f);
    CGPathAddLineToPoint(path, NULL, 60.f, 170.f);
    CGPathAddLineToPoint(path, NULL, 220.f, 280.f);
    CGPathCloseSubpath(path);

    CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    [anim setDuration:10.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所以要手动管理内存。

时间: 2024-11-04 12:02:51

iOS动画——CoreAnimation的相关文章

iOS动画和特效(一)UIView动画和CoreAnimation

一个简单的例子作为iOS动画系类的开始 QuickExampleViewController UIView的方法中有几个易用的静态方法可以做出动画效果,分别是UIView.beginAnimations() -> UIView.commitAnimations() 和UIView.animateWithDuration()方法 我们以一个UIView,每点击一次向右移动100,变色,加速运动这个简单的动效作为例子. 转载请注明出处 使用UIView.beginAnimations() -> U

iOS开发CoreAnimation解读之三——几种常用Layer的使用解析

iOS开发CoreAnimation解读之三——几种常用Layer的使用解析 一.CAEmitterLayer 二.CAGradientLayer 三.CAReplicatorLayer 四.CAShapeLayer 五.CATextLayer iOS开发CoreAnimation解读之三——几种常用Layer的使用解析 一.CAEmitterLayer CAEmitterLayer是CoreAnimation框架中的粒子发射层,在以前的一片博客中有详细的介绍和范例,这里不再重复,地址如下: 粒

iOS开发CoreAnimation解读之二——对CALayer的分析

iOS开发CoreAnimation解读之二——对CALayer的分析 一.UIView中的CALayer属性 1.Layer专门负责view的视图渲染 2.自定义view默认layer属性的类 二.几种系统的Layer类 1.CAEmitterLayer 2.CAGradientLayer 3.CAEAGLLayer 4.CAReplicatorLayer 5.CAScrollLayer 6.CAShapeLayer 7.CATextLayer 8.CATiledLayer 9.CATrans

简析iOS动画原理及实现——Core Animation

本文转载至 http://www.tuicool.com/articles/e2qaYjA 原文  https://tech.imdada.cn/2016/06/21/ios-core-animation/ 主题 Core Animation 背景 随着达达业务的扩大,越来越多的人开始使用达达客户端,参加到众包物流的行业中.达达客户端分为iOS平台和安卓平台. APP开发也从快速迭代的粗旷性开发转向高可复用,提升用户提现的精细化方向发展.iOS动画交互良好,使用广泛,良好的用户体验离不开流畅的界

iOS 动画基础

今天说一下有关动画的基础,希望能帮助到一些刚接触iOS动画或者刚开始学习iOS的同学,如有异议,希望能指正,谢谢. 一.一些基础的概念 下面介绍的都是QuartzCore框架下的内容. 1.CAMediaTimingFunction 时间函数(也被称为缓冲函数),用来描述动画过程中运动的速率情况,也可以看成加速度,apple提供的四种方式: kCAMediaTimingFunctionLinear                  匀速 kCAMediaTimingFunctionEaseIn

如何解决IOS 动画中 Autolayout 与View Transforms的冲突

IOS 的动画放大与缩小,并非按照找它的中心点放大和缩小,而是左上角 .我分析了下原来是Autolayout 与View Transforms的冲突造成的. - (void) addSubviewWithZoomInAnimation:(UIView*)view duration:(float)secs option:(UIViewAnimationOptions)option { // first reduce the view to 1/100th of its original dimen

iOS动画开发之一——UIViewAnimation动画的使用

iOS动画开发之一--UIViewAnimation动画的使用 一.简介 一款APP的成功与否,除了完善的功能外,用户体验也占有极大的比重,动画的合理运用,可以很好的增强用户体验.iOS开发中,常用的动画处理有UIView动画编程和核心动画编程,其中UIView动画使用简便,开发中应用十分广泛.这篇博客,主要讨论UIView的动画使用. 二.UIView动画的几个方法 + (void)animateWithDuration:(NSTimeInterval)duration animations:

iOS动画的要素

1)iOS动画的模型:三层树模型: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreAnimation_guide/CoreAnimationBasics/CoreAnimationBasics.html#//apple_ref/doc/uid/TP40004514-CH2-SW12 Layer Trees Reflect Different Aspects of the Animati

iOS动画浅汇

转自:http://www.cocoachina.com/ios/20160311/15660.html 在iOS开发中,制作动画效果是最让开发者享受的环节之一.一个设计严谨.精细的动画效果能给用户耳目一新的效果,吸引他们的眼光 —— 这对于app而言是非常重要的.我们总是追求更为酷炫的实现,如果足够仔细,我们不难发现一个好的动画通过步骤分解后本质上不过是一个个简单的动画实现.本文就个人搜集的一些动画相关的理论和实践知识做个小结,不足之处请勿见怪. 理论 UIview VS UIlayer UI