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的图片变化,有立体的感觉。
来源:oschina
链接:https://my.oschina.net/u/1032381/blog/483421