UIGestureRecognizers的闭包

时间:2017-04-20 16:23:39

标签: ios swift closures uigesturerecognizer

我想知道,是否可以用块初始化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")
})

...我收到以下错误:

  

由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'+ [MyApp.TapGestureRecognizer runAction]:无法识别的选择器发送到类0x105941598'

知道为什么吗?

1 个答案:

答案 0 :(得分:4)

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

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

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

或者你可以以某种方式将闭包包装在另一个对象中。