我创建了下面的方法作为自定义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关系是什么?