如何以正确的方式对 CABasicAnimation 进行子类化,以便向子类添加自定义属性?

问题描述 投票:0回答:1

这是我在动画完成时调用 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()”

swift cocoa cabasicanimation
1个回答
0
投票

事实证明,扩展

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
© www.soinside.com 2019 - 2024. All rights reserved.