这个问题已经很久没有回答了,但是我会尝试添加一个更快速的解决方案,以防现在有人仍在寻找更干净的解决方案。
如果您感兴趣的只是在 CAAnimation 完成后立即删除该层,您可以将动画的委托分配给一个简单的 NSObject,该 NSObject 包含对目标层的引用并等待动画回调以将其关闭。
让我们将此辅助对象称为 LayerRemover:
class LayerRemover: NSObject, CAAnimationDelegate {
private weak var layer: CALayer?
init(for layer: CALayer) {
self.layer = layer
super.init()
}
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
layer?.removeFromSuperlayer()
}
}
该对象所做的一切都是通过初始化程序接收 CALayer 引用,并在移除层之前等待 animationDidStop 回调。此时,一旦通过委托属性保留它的 CAAnimation 被取消初始化,Layer remover 也会被清除。
现在,您所要做的就是将这个卸妆器实际化并使用它:
let layer = CAShapeLayer()
layer.path = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 200, height: 100)).cgPath
let myAnimation = CABasicAnimation(keyPath: "strokeEnd")
...
myAnimation.delegate = LayerRemover(for: layer)
而已!
请注意,您不必保留对 LayerRemover 对象的任何引用,因为我们可以从Apple 文档中了解到
委托对象由接收者保留。这是高级内存管理编程指南中描述的内存管理规则的罕见例外。