I have been trying to keep a reference to a subclassed CALayer's parent view, but it becomes nil during animation and I would like to know why.
While containerWidth
is animated, parentView
is nil.
198.0648398399353
self.delegate: Optional(<Project.ContainerView: 0x7fc037a05370 ...
parentView: nil
Before and after the animation, parentView
is not 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)")
}
}
During the animation, your layer is copied, and the whole animation is shown on the copied instance of the layer.
In this way CoreAnimation
differs between two states - model state and presentation state. The layer which you work with, carries model state, and animation is rendered on presentationLayer
.
Presentation layer is created via init(layer: Any)
initialiser, where layer
argument is the model layer.
You can assign the required properties in this initialiser from the model layer to the presentation layer, like this:
class ContainerLayer: CALayer {
private override init(layer: Any) {
super.init(layer: layer)
if let containerModelLayer = layer as? ContainerLayer {
self.parentView = containerModelLayer.parentView
}
}
...
}