为什么在动画期间 属性 引用 CALayer 的父视图是 'nil'

Why would a property to reference a CALayer's parent view be 'nil' during animation

我一直试图保留对子类 CALayer 的父视图的引用,但在动画期间它变为 nil,我想知道为什么。

虽然 containerWidth 是动画,但 parentView 是 nil。

198.0648398399353
self.delegate: Optional(<Project.ContainerView: 0x7fc037a05370 ...
parentView: nil

动画前后,parentView不为nil

200.0
self.delegate: Optional(<Project.ContainerView: 0x7fc037a05370 ...
parentView: Optional(<Project.ContainerView: 0x7fc037a05370 ...
class ContainerLayer: CALayer {
    var didSetup = false
    var parentView: ContainerView!
    @NSManaged var containerWidth: CGFloat

    override func layoutSublayers() {
        super.layoutSublayers()
        if !self.didSetup {
            parentView = self.delegate as? ContainerView
            self.didSetup = true
        }
    }
    override class func needsDisplay(forKey key: String) -> Bool {
        if key == #keyPath(containerWidth) {
            return true
        }
        return super.needsDisplay(forKey: key)
    }

    override func draw(in ctx: CGContext) {
        print(containerWidth)
        print("self.delegate: \(self.delegate)")
        print("parentView: \(parentView)")
    }
}

在动画播放过程中,您的层被复制,整个动画显示在层的复制实例上。

这样 CoreAnimation 两种状态之间存在差异 - 模型状态和呈现状态。您使用的图层承载模型状态,动画在 presentationLayer.

上呈现

表示层是通过 init(layer: Any) 初始化程序创建的,其中 layer 参数是模型层。

您可以将此初始化程序中的所需属性从模型层分配给表示层,如下所示:

class ContainerLayer: CALayer {

    private override init(layer: Any) {
       super.init(layer: layer)
       if let containerModelLayer = layer as? ContainerLayer {
           self.parentView = containerModelLayer.parentView
       }
    }
    
    ...
}