UIGestureRecognizer 的闭包

Closures for UIGestureRecognizers

我在想,是否可以用一个块来初始化一个 UIGestureRecognizer,而不必为它创建一个单独的函数。
在 Swift 3 中,我相信,这是为计时器引入的。

我已经实现了与 here 发布的代码类似的东西,因为它对我不起作用。
这是我的代码:

class TapGestureRecognizer: UITapGestureRecognizer {
    private var closure: (() -> ())?

    init() {
        super.init(target: TapGestureRecognizer.self, action: #selector(self.runAction))
    }

    convenience init(for view: UIView, block: @escaping (() -> Void)) {
        self.init()
        closure = block
        view.addGestureRecognizer(self)
    }

    func runAction() {
        print("executed")
        if closure == nil { return }
        closure!()
    }    
}

当我像这样创建 TapGestureRecognizer 时:

TapGestureRecognizer(block: { _ in
    print("tapped")
})

...我收到以下错误:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[MyApp.TapGestureRecognizer runAction]: unrecognized selector sent to class 0x105941598'

知道为什么吗?

你的问题是你的目标是 TapGestureRecognizer class 本身。您的 runAction 方法是 instance 方法,但您告诉 super.init 它是 class 方法,因此此处失败:+[MyApp.TapGestureRecognizer runAction]。您可以通过将 runAction 设为 class 方法来解决此问题。

您还可以删除 class 上的目标并在初始化后添加实例:

init() {
    super.init(target: TapGestureRecognizer.self, action: #selector(runAction))
    self.removeTarget(TapGestureRecognizer.self, action: #selector(runAction))
    self.addTarget(self, action: #selector(runAction))
}

或者您可以以某种方式包装要在不同对象中触发的闭包。