上文简单讲述了CALayer的概念以及一些属性,针对于Layer,除了其展示样式,我们更注重它的动画,本篇文章及本专栏的后续文章将围绕Layer的核心动画进行探究。
本文首先看一下CALayer的基础动画类CABasicAnimation以及CATransaction的使用。
CALayer基础动画类为CABasicAnimation,看一下官方的定义:
An object that provides basic, single-keyframe animation capabilities for a layer property.
一个能够给Layer提供基础的单个关键帧动画能力的对象。
常用方法及属性见下表:
属性及方法 | 类型 | 说明 |
---|---|---|
init(keyPath: String?) |
/ | 初始化方法 |
fromValue |
Any? |
动画执行初始值 |
toValue |
Any? |
动画执行结束值 |
byValue |
Any? |
动画执行的结束值与初始值的差值 |
keyPath |
String? |
指定执行动画的key path |
isRemovedOnCompletion |
Bool |
动画执行结束后是否从目标图层中移除。设置为false解决动画恢复到初始位置的问题。 |
fillMode |
CAMediaTimingFillMode |
removed:默认值,动画开始前和结束后,动画对图层都没有影响,图层依然保持初始值。 forwards:动画结束后保持最终的可见状态。 backwards:动画开始前,只要加入动画,图层就会处于动画的初始状态,即第一帧动画。 both:综合了forwards和backwards两种功能,动画加入图层到真正执行动画的时间段里,图层保持动画初始状态;动画结束之后保持动画最终状态 |
duration |
CFTimeInterval |
动画执行时长 |
repeatCount |
Float |
动画执行次数 |
repeatDuration |
CFTimeInterval |
动画多久后执行一次。 |
创建动画的时候可通过init(keyPath: String?)方法实例化一个对象,并指定一个属性的keyPath用于动画。
可以将一个标量属性(有具体的数值)添加动画,比如不同明度(opacity),将其值从0设置到1,代码如下:
override func viewDidLoad() {
super.viewDidLoad()
layer.frame = CGRect(x: 20, y: 60, width: 100, height: 100)
layer.backgroundColor = UIColor.red.cgColor
self.view.layer.addSublayer(layer)
}
override func touchesBegan(_ touches: Set, with event: UIEvent?) {
let animation = CABasicAnimation(keyPath: "opacity")
animation.fromValue = 0
animation.toValue = 1
animation.duration = 2
animation.isRemovedOnCompletion = false
animation.fillMode = .forwards
layer.add(animation, forKey: nil)
}
上面创建了一个红色的layer,并将其添加到了当前view的layer中,当点击屏幕的时候,修改红色layer的opacity。
一些非标量属性,比如背景色(backgroundColor),其值变化也可以加入动画,代码如下,重复代码不在提现:
let animation = CABasicAnimation(keyPath: "backgroundColor")
animation.fromValue = UIColor.red.cgColor
animation.toValue = UIColor.blue.cgColor
还给可给一些多值的属性添加动画,比如位置信息(position),代码如下:
let animation = CABasicAnimation(keyPath: "position")
animation.fromValue = [0, 0]
animation.toValue = [100, 100]
除了以上,还可以给某个属性的里面的某个值添加动画,例如:
let animation = CABasicAnimation(keyPath: "transform.scale.x")
animation.fromValue = 1
animation.toValue = 2
以上便是一些基础动画的创建,至于哪些keyPath可以执行动画,具体如下:
CATransform3D Key Paths
Key Path |
Description |
---|---|
transform. |
设置一个沿着x轴旋转的弧度值。 关于π,Swift 3.0以后请使用Doubl.pi |
transform. |
设置一个沿着y轴旋转的弧度值。 |
transform. |
设置一个沿着z轴旋转的弧度值。 |
transform. |
设置一个沿着z轴旋转的弧度值,同transform. |
transform. |
设置一个沿着x轴放缩的比例因子。 |
transform. |
设置一个沿着y轴放缩的比例因子。 |
transform. |
设置一个沿着z轴放缩的比例因子。 |
transform. |
设置一个整体放缩的比例因子。 |
transform. |
设置一个沿着x轴移动的值。 |
transform. |
设置一个沿着y轴移动的值。 |
transform. |
设置一个沿着z轴移动的值。 |
transform.translation |
设置一个结构体类型的值,例如CGSize,CGPoint,其值表示沿着x轴和y轴移动的数值。 |
CGPoint Key Paths
Key Path |
Description |
---|---|
position. |
设置一个中心点沿着x轴移动的值。 |
position. |
设置一个中心点沿着y轴移动的值。 |
CGSize Key Paths
Key Path | Description |
---|---|
|
设置一个宽度变换的值。 |
|
设置一个高度变换的值。 |
CATransaction是将Layer tree多个操作批处理为渲染树的原子更新的核心动画机制。对Layer tree的每个修改都必须是CATransaction的一部分。支持嵌套CATransaction。
Core Animation支持两种类型的CATransaction:implicit transactions(隐式)和explicit transactions(显式)。
implicit transactions在没有活动transactions的线程修改layer tree的时候自动创建,并在线程runloop下一次迭代的时候自动提交。
explicit transactions则是在修改layer tree之前向CATransaction类发送begin()消息,修改后发送commit()消息时时候触发。
常用类方法如下表:
类方法 | 说明 |
---|---|
class func begin() |
在当前线程创建一个transaction。 |
class func commit() |
提交当前transaction的所有修改。 |
class func flush() |
刷新任何存在的隐式transaction. |
class func animationDuration() -> CFTimeInterval |
返回在transaction组中所有动画的执行时间。 |
class func setAnimationDuration(CFTimeInterval) |
设置transaction组中所有动画的执行时间。 |
class func completionBlock() -> (() -> Void)? |
返回动画结束后的block对象。 |
class func setCompletionBlock((() -> Void)?) |
设置动画结束后的block对象。 |
关于隐式动画,我们不需要添加额外的代码,系统会自己处理,比如在改变backgroundColor的时候,颜色会从一个到另一个颜色渐变过去,系统的动画时间为0.25秒。
至于显示动画,则需要我们手动添加代码了。
先看一段简单的代码,将一个Layer的的size变成原来的两倍,并改变其背景色。
func transactionAnimation() {
CATransaction.begin()
let transform = CATransform3DScale(layer.transform, 2, 2, 2)
layer.transform = transform
CATransaction.setAnimationDuration(2)
CATransaction.setCompletionBlock {
self.layer.backgroundColor = UIColor.blue.cgColor
}
CATransaction.commit()
}
下面看一个显示的嵌套CATransaction,Layer从不透明到透明,然后移除,期间size变为原来的3倍。
func transactionNestedAnimation() {
// Outer transaction animates `opacity` to 0 over 2 seconds
CATransaction.begin()
CATransaction.setAnimationDuration(2)
layer.opacity = 0
CATransaction.setCompletionBlock {
self.layer.removeFromSuperlayer()
}
// Inner transaction animates scale to (3, 3, 3) over 1 second
CATransaction.begin()
CATransaction.setAnimationDuration(2)
layer.transform = CATransform3DMakeScale(3, 3, 3)
CATransaction.commit() // Commits inner transaction
CATransaction.commit() // Commits outer transaction
}
本文主要讲述了CABasicAnimation以及CATransaction两种动画,作为基础动画,用起来并不难,文中也列举了常用的一些方法和属性等。
文中如有不正确的地方,还请路过的朋友指正。
本篇文章出自https://blog.csdn.net/guoyongming925的博客,如需转载,请标明出处。