【问题标题】:Re-use animation throughout iOS views在整个 iOS 视图中重用动画
【发布时间】:2017-01-11 12:21:03
【问题描述】:

不确定我的想法是否正确,但我在整个 iOS 项目中使用了类似的动画,我想将其压缩为 1 个文件并在任何我想要的地方重复使用。

一个简单的例子。在我的动画文件中,我有一个缩放动画

Animations.swift

class Animations {

    class func scaleSmall(_ view: UIView) {
        let scaleAnim = POPBasicAnimation(propertyNamed: kPOPLayerScaleXY)
        scaleAnim?.toValue = NSValue(cgSize: CGSize(width: 0.9, height: 0.9))
        view.layer.pop_add(scaleAnim, forKey: "scaleSmallAnim")
    }

}

我的 View 文件夹中有许多 swift 文件之一,我想将该动画添加到按钮

Button.swift

class Button: UIButton {

    override func awakeFromNib() {
        super.awakeFromNib()

        self.addTarget(self, action: #selector(Animations.scaleSmall(_:)), for: .touchDown)
    }

}

我以为我可以从其他文件中引用动画,但是每次我这样做时都会遇到同样的错误

'#selector' 的参数是指没有暴露给 Objective-C 的实例方法 'scaleSmall'

我引用这个函数有错吗?

【问题讨论】:

  • 你做得对。只是 Swift 类与 Obj-C 不完全兼容,UIKit(即UIButton)在 Obj-C 世界中。您可以尝试通过Animations 类从NSObject 继承或将您的方法标记为@objc
  • 令我困惑的是,如果我的 Button 类中有动画,我可以使用 #selector(Button.scaleSmall) 访问它并且它可以正常工作。一旦我把它从文件中拿出来,我就无法正确地得到它

标签: ios swift animation addtarget


【解决方案1】:

尝试更改class func scaleSmall(_ view: UIView) {

 @objc class func scaleSmall(view: UIView) {

【讨论】:

  • 尽量保持一个干净的 swift 文件,如果我不需要的话,不要混淆 objc
  • 这并不是真正将 objc 与 swift 代码混合,函数前的 @objc 只是编译器的标志。
  • 所以它消除了我的错误,但我遇到的下一个问题是应用程序失败“发送到实例的无法识别的选择器”。现在做一些调查
  • 这可能是因为您将self 作为目标传递。这意味着按钮实际上是在尝试调用self 上的方法。我实际上从未尝试使用静态方法作为按钮的选择器。也许通过 Animation 类的单例来实现它会起作用。
【解决方案2】:

我已经确认了我的评论,所以我发布了一个答案。 UIButton 的方法需要桥接到 Obj-C。这也是@Kostas Tsoleridis 在他的回答中所建议的 - 它不是在一个文件中混合两种语言,您只是在为编译器标记方法。其他解决方案是通过 Animations 类从 NSObject 继承。

现在,正如您在评论中提到的困惑 - 它起作用了,因为您的 Button 类继承自 UIButton ,它既来自 Obj-C 世界,也继承自 NSObject

还要解决@Kostas Tsoleridis 回答下的评论中提到的问题(老实说,我之前应该考虑过) - 你不能将self 作为目标传递并使用另一个类的方法(甚至是静态的)。要解决这个问题,您可以使用 Animations 类的单例实例,如下所示:

class Animations {
    static let sharedInstance = Animations()
    @objc class func scaleSmall(_ view: UIView) {
        // your code
    }
}

let button = UIButton()
button.addTarget(Animations.sharedInstance, action: #selector(Animations.scaleSmall(_:)), for: .touchDown)

【讨论】:

  • 我开始看看你们现在在说什么
猜你喜欢
  • 2013-12-21
  • 1970-01-01
  • 1970-01-01
  • 2012-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-17
  • 2021-06-28
相关资源
最近更新 更多