我创建了下面的方法作为自定义CAAnimationGroup的一部分 . 该方法首先将其自身添加到对初始化时分配的CALayer的弱引用 .
然后它迭代它自己的 animations
数组,并在弱CALayer引用上使用 KVC 将每个动画的 toValue
应用于关联的 keyPath
.
final public class FAAnimationGroup : CAAnimationGroup {
weak var weakLayer : CALayer?
override init() {
super.init()
animations = [CAAnimation]()
fillMode = kCAFillModeForwards
removedOnCompletion = true
}
override public func copyWithZone(zone: NSZone) -> AnyObject {
let animationGroup = super.copyWithZone(zone) as! FAAnimationGroup
animationGroup.weakLayer = weakLayer
return animationGroup
}
......
func applyFinalState() {
guard let animationLayer = weakLayer else {
return
}
animationLayer.addAnimation(self, forKey: self.animationKey)
if let groupAnimations = animations {
for animation in groupAnimations {
if let toValue = animation.toValue {
animationLayer.setValue(toValue, forKeyPath: animation.keyPath!)
}
}
}
}
}
因此,对于所有视图的边界,大小,变换和alpha都可以正常工作,就像当前的 removedOnCompletion
标志和 fillMode
值一样 .
动画完成后,我查询UIView,它是后备层 . 看到的是框架反映了正确的结果,视图的alpha反映了动画的不透明度值 . 大!
但这里有趣的部分 . 当动画UISlider的不透明度从0.0到1.0时 . 动画完成后,我开始调整UISlider值,当我移动它时,alpha会回到0.0 .
我试图将 removedCompletion
标志设置为 false ,并且如预期的那样,保持动画保持图层处于最终状态,但这不是我想要的 . 我需要它在完成后自行移除,因为我确实直接在背衬层上设置了值 .
所以在将 removedCompletion
设置回 true 之后,我尝试了下面的内容,让我完全难过,直到我的问题....
.....
if let groupAnimations = animations {
for animation in groupAnimations {
if let toValue = animation.toValue {
if animation.keyPath! == "opacity" {
animationLayer.owningView()!.setValue(toValue, forKeyPath: "alpha")
} else {
animationLayer.setValue(toValue, forKeyPath: animation.keyPath!)
}
}
}
}
在上面的代码中,我不是在图层上设置不透明度,而是在与动画图层关联的owningView上设置alpha值(也就是图层的委托) . 在这种情况下,一切都相应,我调整了滑块,它没有重置为alpha 0.0
事实上只有UISlider才会发生这种情况可能无关紧要 . 我认为通过设置UIView的属性,后备层将反映等效,我假设反之亦然 .
Question
为什么在设置视图的alpha时,最终的alpha / opacity值是同步的,但是当我在其背景层上设置不透明度时却没有反映出来?在这个具体的例子中,UIView和CALayer之间有什么关系?
根据我的理解,这两者是非常错综复杂的相互关联,UIView是一种包装器,完全可以访问相应的重绘自己的后备层 . 在动画的上下文中,这种不透明度/ alpha关系是什么?