47

Why doesn't this work in swift 3 ? It crashes at runtime saying:

'-[my_app_name.displayOtherAppsCtrl tap:]: unrecognized selector sent to instance 0x17eceb70'

    override func viewDidLoad() {
    super.viewDidLoad()

    // Uncomment the following line to preserve selection between presentations
    // self.clearsSelectionOnViewWillAppear = false

    // Register cell classes
    //self.collectionView!.register(ImageCell.self, forCellWithReuseIdentifier: reuseIdentifier)

    // Do any additional setup after loading the view.

  let lpgr = UITapGestureRecognizer(target: self, action: Selector("tap:"))
    lpgr.delegate = self
    collectionView?.addGestureRecognizer(lpgr)
}

func tap(gestureReconizer: UITapGestureRecognizer) {
if gestureReconizer.state != UIGestureRecognizerState.ended {
  return
}

let p = gestureReconizer.location(in: self.collectionView)
let indexPath = self.collectionView?.indexPathForItem(at: p)

if let index = indexPath {
  //var cell = self.collectionView?.cellForItem(at: index)
  // do stuff with your cell, for example print the indexPath
  print(index.row)
} else {
  print("Could not find index path")
}
}
Gherbi Hicham
  • 2,416
  • 4
  • 26
  • 41
Chris
  • 1,231
  • 2
  • 10
  • 20

4 Answers4

125

Selector("tap:") should now be written as #selector(tap(gestureReconizer:))

Also, you should declare tap as func tap(_ gestureRecognizer: UITapGestureRecognizer) as per the new Swift API Guidelines in which case your selector would then become #selector(tap(_:)).

jjatie
  • 5,152
  • 5
  • 34
  • 56
  • 5
    You have to write it this way : `#selector(ClassName.MethodName)` Otherwise you can have an error about objc selector. – RoaflinSabos Feb 28 '17 at 14:34
  • @RoaflinSabos You only need to include a class name if the method is outside of the class the selector is declared in. It also does not affect Objective-C visibility. – jjatie Aug 14 '17 at 17:52
19

In Swift 3 it works like this:

@IBOutlet var myView: UIView!
override func viewDidLoad() {
    super.viewDidLoad()

    let tap = UITapGestureRecognizer(target: self, action:#selector(handleTap))

    myView.addGestureRecognizer(tap)
}

func handleTap() {
    print("tapped")
}
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
Neen
  • 361
  • 4
  • 5
  • 2
    This is great as it shows you have to init the UITapGestureRecognizer inside a method ... I was having major issues because I was (albeit dumbly) declaring and init'ing the tap at the top of the file. Poor debugging messages ensued, and it took quite a while to solve :S ... to be noted, if you make the function private, you seemingly must add @objc before the "private func ..." – Chris Allinson Feb 20 '17 at 19:26
2

Swift 3 came with new syntax so instead of using Selector("tap:"), #selector(tap(gestureReconizer:)) is

Zeeshan
  • 51
  • 5
0

Swift 3:

class MYPTempController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let btn = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        view.addSubview(btn)
        btn.addTarget(self, action: #selector(MYPTempController.btnClick), for: .touchUpInside)
    }
    @objc fileprivate func btnClick() {
        print("--click--")
    }
}

//带参数
btn.addTarget(self, action: #selector(MYPTempController.btnClick(_:)), for: .touchUpInside)
//监听方法
func btnClick(_ sender: UIButton) {
    print("--click--")
}
GeekMeng
  • 1
  • 3