先介绍一下CAAnimation的代理方法。CAAnimationDelegate有两个可选代理方法:
func animationDidStart(_ anim: CAAnimation)
func animationDidStop(_ anim: CAAnimation, finished flag: Bool)
CABasicAnimation继承至CAAnimation。它们都是使用Objective-C编写的,并且它们遵从key-value编码风格,意思是你可以把它当做字典,可以在运行时为它们添加新的属性。
我们继续使用之前创建的CABasicAnimation对象flyRight。例如:
flyRight.setValue("form", forKey: "name")
现在你能在它的代理方法里面根据name来判断是否是当前animation的拷贝。你也可以为其分配一个username.layer,以便保留对某个layer的引用。例如
flyRight.setValue(username.layer, forKey: "layer")
flyRight.setValue(password.layer, forKey: "layer")
整个代码如下:
let flyRight = CABasicAnimation(keyPath: "position.x")
flyRight.fromValue = -view.bounds.size.width/2
flyRight.toValue = view.bounds.size.width/2
flyRight.duration = 0.5
flyRight.delegate = self
flyRight.setValue("form", forKey: "name")
flyRight.setValue(heading.layer, forKey: "layer")
heading.layer.add(flyRight, forKey: nil)//拷贝一份flyRight到heading.layer
flyRight.beginTime = CACurrentMediaTime() + 0.3
flyRight.fillMode = kCAFillModeBoth
flyRight.setValue(username.layer, forKey: "layer")
username.layer.add(flyRight, forKey: nil)//拷贝一份flyRight到username.layer
flyRight.beginTime = CACurrentMediaTime() + 0.4
flyRight.setValue(password.layer, forKey: "layer")
password.layer.add(flyRight, forKey: nil)//拷贝一份flyRight到password.layer
代理方法实现:
func animationDidStop(_ anim: CAAnimation,
finished flag: Bool) {
print("animation did finish")
guard let name = anim.value(forKey: "name") as? String else {
return
}
if name == "form" {
//form field found
let layer = anim.value(forKey: "layer") as? CALayer
anim.setValue(nil, forKey: "layer")//动画完成后移除对layer的引用
let pulse = CABasicAnimation(keyPath: "transform.scale")//开始一个新的动画
pulse.fromValue = 1.25
pulse.toValue = 1.0
pulse.duration = 0.25
layer?.add(pulse, forKey: nil)
}
}
例子:为名为info的label添加两个动画
let flyLeft = CABasicAnimation(keyPath: "position.x")
flyLeft.fromValue = info.layer.position.x +
view.frame.size.width
flyLeft.toValue = info.layer.position.x
flyLeft.duration = 5.0
flyLeft.repeatCount = 2.5
flyLeft.speed = 2.0
flyLeft.autoreverses = true
info.layer.add(flyLeft, forKey: "infoappear")
let fadeLabelIn = CABasicAnimation(keyPath: "opacity")
fadeLabelIn.fromValue = 0.2
fadeLabelIn.toValue = 1.0
fadeLabelIn.duration = 4.5
info.layer.add(fadeLabelIn, forKey: "fadein")
repeatCount:重复次数
autoreverses:自动反转
speed:动画执行速度,尽管我们把duration设置为5秒,因为我们提高了动画执行速度,所以最后我们只需要2.5秒即可执行完整个 动画。
另外介绍两个方法
- info.layer.animationKeys():我们可以获取该layer所有animation的key值
- info.layer.removeAnimation(forKey: “infoappear”):移除该layer下key为infoappear的动画
如果你想在一个layer上同步执行多个动画,你也可以使用CAAnimationGroup,后面会介绍。