这是我在动画完成时调用 CABasicAnimation 的工作代码。我得到了动画委托所需的操作,但我希望能够在 CABasicAnimation 的子类上完成这项工作:
extension NSView {
func fadeAnimation(callBack: @escaping () -> Void) {
let animation = CABasicAnimation()
animation.delegate = CustomCAAnimationDelegate(callBack: callBack)
animation.keyPath = "opacity"
animation.duration = 2.0
animation.fromValue = 1.0
animation.toValue = 0.0
animation.timingFunction = CAMediaTimingFunction(name: .linear)
animation.isRemovedOnCompletion = false
animation.fillMode = .forwards
self.layer?.add(animation, forKey: nil)
}
}
class CustomCAAnimationDelegate: NSObject, CAAnimationDelegate {
var callBack: () -> Void
init(callBack: @escaping () -> Void) {
self.callBack = callBack
}
internal func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
callBack()
}
}
所以目标是有这样的代码:
class CustomCABasicAnimation: CABasicAnimation {
var callBack: () -> Void
}
如果完成,我将能够像这样编写代码:
extension NSView {
func fadeAnimation(callBack: @escaping () -> Void) {
let animation = CustomCABasicAnimation()
animation.callBack = callBack
// The other codes ...
}
}
我已经实现了我的自定义动画类如下:
class CustomCABasicAnimation: CABasicAnimation {
var callBack: () -> Void
init(callBack: @escaping () -> Void) {
self.callBack = callBack
super.init()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
当我运行代码时出现错误:
线程 1:EXC_BAD_INSTRUCTION(代码=EXC_I386_INVOP,子代码=0x0)
和:
Fade_Test/ViewController.swift:57: 致命错误:对类“Fade_Test.CustomCABasicAnimation”使用未实现的初始化程序“init()” 2023-03-17 23:39:59.577008+0100 淡入淡出测试[1810:79953] Fade_Test/ViewController .swift:57: 致命错误:对类“Fade_Test.CustomCABasicAnimation”使用未实现的初始化程序“init()”
事实证明,扩展
CABasicAnimation
并不像看起来那么简单。
CABasicAnimation
的文档指出:
您使用继承的 init(keyPath:) 方法创建 CABasicAnimation 实例,指定要在渲染树中设置动画的属性的关键路径。
所以你的
CustomCABasicAnimation
只能添加新属性,但不能添加初始化程序。这意味着您的 callBack
属性必须是可选的。
class CustomCABasicAnimation: CABasicAnimation {
var callBack: (() -> Void)?
}
您可以根据需要添加/覆盖其他方法以使用可选的
callBack
.
现在您创建的
CustomCABasicAnimation
必须看起来更像这样:
let animation = CustomCABasicAnimation(keyPath: "opacity")
animation.callBack = callBack
// other properties as needed