我创建了下面的方法作为自定义CAAnimationGroup的一部分。该方法首先将其自身添加到对初始化时分配的CALayer的弱引用。
然后它迭代它自己的animations
数组,并使用弱CALayer引用上的 KVC 将每个动画的toValue
应用于关联的keyPath
。< / p>
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的属性,后备层将反映等效,我认为反之亦然也是如此。
问题
为什么在设置视图的alpha时,最终的alpha / opacity值是同步的,但是当我在其背景层上设置不透明度时却没有反映出来?在这个具体的例子中,UIView和CALayer之间有什么关系?
根据我的理解,这两者是非常错综复杂的相互关联,UIView是一种包装器,它完全可以访问后备层,相应地重绘自身。动画上下文中的这种不透明度/ alpha关系是什么?