Core Animation学习笔记

我的未来我决定 提交于 2020-12-18 00:53:51

Core Animation的基类为CAAnimation,使用起来还是比较简单方便的,可是实现绚丽的动画效果,步骤可分为如下三步

    a. 创建一个CAAnimation的子类对象

    b. 为该对象添加一些属性

    c. 为需要执行该动画视图的layer添加该动画

看一个简单的例程

var aview = UIView(frame: CGRectMake(20, 20, 80, 80))
aview.backgroundColor = UIColor.blackColor()
self.view.addSubview(aview)
var basicAnimation = CABasicAnimation(keyPath: "transform.scale")
basicAnimation.fromValue = 0.5
basicAnimation.toValue = 1.0
basicAnimation.duration = 2.0
basicAnimation.repeatCount = 3
aview.layer.addAnimation(basicAnimation, forKey: "scale")

首先创建了一个CAAnimation的子类CABasicAnimation,由于CAAnimation为抽象类,需要使用时,需要使用其子类。CAAnimation的类层次图为

其中可实例化的为CABasicAnimation,CAKeyFrameAnimation,CATransiton,CAAnimationGroup。

1. CABasicAnimation

1.1 初始化方法

    CABasicAnimation的初始化方法集成自CAPropertyAnimation,其中传入的参数keyPath,有多种值可选通过指定CALayer的这个个属性,并且对CALayer的这个属性的值进行修改,达到相应的动画效果。常用的有:transform.scale,transform.rotation,opacity,backgroundColor,frame,position等等。

其余可参考这篇文章:http://blog.sina.com.cn/s/blog_66c830cf0102v9t4.html

完成初始化之后需要对动画需要展现的属性进行配置:

1.2 父类CAAnimation中定义的属性有

    duration:动画的持续时间

    repeatCount:动画的重复次数

    repeatDuration:动画的重复时间

    removedOnCompletion:默认为true,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。如果想让图层保持显示动画执行后的状态,那就设置为false,不过还要设置fillMode为kCAFillModeForwards。

    beginTime:可以用来设置动画延迟执行时间,若想延迟2s,就设置为CACurrentMediaTime()+2,     CACurrentMediaTime()为图层的当前时间。

    timingFunction:速度控制函数,控制动画运行的节奏。

    速度控制函数(CAMediaTimingFunction)

    使用方法animation.timingFunction = CAMediaTimingFunction(name:),可传入:

        kCAMediaTimingFunctionLinear(线性)

        kCAMediaTimingFunctionEaseIn(渐进)

        kCAMediaTimingFunctionEaseOut(渐出)

        kCAMediaTimingFunctionEaseInEaseOut(渐进渐出)

     delegate,使用时需要设置animation.delegate = self,并且重写animationDidStart和animationStop方法。

    fillMode属性值(需要设置removedOnCompletion=false)

    kCAFillModeRemoved这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态
。

    kCAFillModeForwards当动画结束后,layer会一直保持着动画最后的状态。

    
kCAFillModeBackwards在动画开始前,你只要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始. 你可以这样设定测试代码,将一个动画加入一个layer的时候延迟5秒执行。然后就会发现在动画没有开始的时候,只要动画被加入了layer,ayer便处于动画初始状态。

    kCAFillModeBoth这个其实就是上面两个的合成。动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状。

1.3 CABasicAnimation中定义的属性

    fromValue:keyPath相应属性的初始值。

    toValue:keyPath相应属性的结束值。

    随着动画的进行,在长度为duration的持续时间内,keyPath相应属性的值从fromValue渐渐地变为toValue。

    如果fillMode=kCAFillModeForwards和removedOnComletion=false,那么在动画执行完毕后,图层会保持显示动画执行后的状态。但在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变。比如,CALayer的position初始值为(0,0),CABasicAnimation的fromValue为(10,10),toValue为(100,100),虽然动画执行完毕后图层保持在(100,100)这个位置,实质上图层的position还是为(0,0)。

2. CAKeyframeAnimation

    CAPropertyAnimation的子类,跟CABasicAnimation的区别是:

    CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个数组保存一个变化的轨迹。CABasicAnimation可看做是轨迹只有两个点的CAKeyframeAnimation。

2.1 属性分析

    values:就是上述的NSArray对象。里面的元素称为”关键帧“(keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧。

    path:可以设置一个CGPathRef\CGMutablePathRef,让层跟着路径移动。path只对CALayer的anchorPoint和position起作用。如果你设置了path,那么values将被忽略。

    看一段使用path属性的代码:可构建一个圆形路径

var path = CGPathCreateMutable()
CGPathAddEllipseInRect(path, nil, CGRectMake(40, 40, 100, 100))
keyAnimation.path = path

    keyTimes:可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0。keyTimes中的每一个时间值都对应values中的每一帧,当keyTimes没有设置的时候,各个关键帧的时间是平分的。

    在关键帧动画中还有一个非常重要的参数,那便是calculationMode,计算模式。其主要针对的是每一帧的内容为一个座标点的情况,也就是对anchorPoint和position进行的动画。当在平面座标系中有多个离散的点的时候,可以是离散的,也可以直线相连后进行插值计算,也可以使用圆滑的曲线将他们相连后进行插值计算。calculationMode目前提供如下几种模式:


    kCAAnimationDiscrete:离散的,帧与帧之间,没有过度效果,之间变到下一帧。    

    kCAAnimationLinear:calculationMode的默认值,帧与帧之间匀速过度。

    
kCAAnimationPaced:使得动画均匀进行,而不是按keyTimes设置的或者按关键帧平分时间,此时keyTimes和timingFunctions无效;

    
kCAAnimationCubic:对关键帧为进行圆滑曲线相连后插值计算,这里的主要目的是使得运行的轨迹变得圆滑,当关键帧存在角度(例如90°C的之间转弯,可以起到光滑轨迹的作用);

    kCAAnimationCubicPaced:是在kCAAnimationCubic的基础上使得动画运行变得均匀,就是系统时间内运动的距离相同,此时keyTimes以及timingFunctions也是无效的。

3. CAAnimationGroup

    CAAnimation的子类,可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行。

    animations:用来保存一组动画对象的数组。

    默认情况下,一组动画对象是同时运行的,也可以通过设置动画对象的beginTime属性来更改动画的开始时间。

    看一个例程:

var basicAnimation1 = CABasicAnimation(keyPath: "transform.rotation")
basicAnimation1.fromValue = 0
basicAnimation1.toValue = M_PI / 3
basicAnimation1.duration = 5.0
basicAnimation1.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)

var basicAnimation2 = CABasicAnimation(keyPath: "position")
basicAnimation2.fromValue = NSValue(CGPoint: CGPoint(x: aview.center.x, y: aview.center.y))
basicAnimation2.toValue = NSValue(CGPoint: CGPoint(x: aview.center.x + 200, y: aview.center.y))
basicAnimation2.duration = 5.0
basicAnimation2.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)

var group = CAAnimationGroup()
group.delegate = self
group.animations = [basicAnimation1, basicAnimation2];
group.duration = 5.0 // 必须单独设置
aview.layer.addAnimation(group, forKey: "group")

group的duration必须单独赋值,否则动画会在瞬间完成,而忽略掉两个成员的duration

4. CATransition

    CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。

4.1 属性解析

    type:动画过渡类型(fade, reveal, moveIn, push, cube)

    subtype:动画过渡方向(fromTop, fromBottom, fromLeft, fromRight)

    startProgress:动画起点(在整体动画的百分比) 0~1

    endProgress:动画终点(在整体动画的百分比) 0~1

    看一个转场的简单例程:

var tr: CATransition = CATransition()
//告诉要执行什么动画
tr.type = "cube";
//设置动画的过度方向(向左)
tr.subtype = kCATransitionFromLeft;
//设置动画的时间
tr.duration = 1.0;
//添加动画
self.imageView.layer.addAnimation(tr, forKey: "tran")
self.imageView.image=UIImage(named: String(format: "album%@", arguments: ["2"]));

这个程序用cube实现了UIImageView的图片变化,有立体的感觉。 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!