为什么在动画过程中引用CALayer父视图的属性为“ nil”

问题描述

我一直试图保留对CALayer子类的父视图的引用,但是在动画制作过程中它变为nil,我想知道为什么。

containerWidth设置动画时,parentView为零。

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

在动画前后,parentView不为零。

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
       }
    }
    
    ...
}