I am trying to add a UITapGestureRecognizer to a UIViewController via a swift protocol extension. I run into a problem when I try intialize the tapGestureRecognizer with a #selector. I have setup the following in a playground
protocol Tapable {
func setupTapGestureRecognizerInView(view: UIView)
func didTap(sender: UITapGestureRecognizer)
}
extension Tapable where Self: UIViewController {
func setupTapGestureRecognizerInView(view: UIView) {
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.didTap(_:)))
tapGesture.numberOfTapsRequired = 1
view.addGestureRecognizer(tapGesture)
}
func didTap(sender: UITapGestureRecognizer) {
}
}
class SomeViewController: UIViewController, Tapable {
}
In the above scenario, I get a compiler error with the message "Argument of #selector refers to a method that is not exposed to Objective-C
I can fix the compiler error if I prepend the protocol declaration with @objc
i.e
@objc protocol Tapable {
func setupTapGestureRecognizerInView(view: UIView)
func didTap(sender: UITapGestureRecognizer)
}
However, if I add the @objc
, I get a compiler error in the UIViewController saying that "Type SomeViewController does not conform to protocol 'Tapable'". It also suggests a Fix-it "Canditate is not @objc but protocol requires it".
Tapping this Fix-it prepends the setupTapGestureRecognizer with @objc in the extension (i.e. @objc func setupTapGestureRecognizerInView(view: UIView) {
,
however this does not resolve the compiler error and also causes a second compiler error which tells me to do delete the @objc that the Fix-it just added
How can I add a #selector via a protocol extension for a UIViewController?