1

I am using a custom cell with UICollectionView, I need to define UIButton programmatically per cell.

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! ClinicListCell
    cell.title.text = clinicNames[indexPath.row]
    cell.subTitle.text = clinicSubs[indexPath.row]
    cell.backgroundImageView.image = UIImage(named: clinicImages[indexPath.row])
    cell.profileBtn.tag = indexPath.row
    cell.profileBtn.addTarget(self, action: Selector(("profileBtnClicked:")), for: .touchUpInside)
    return cell
}

And I have defined the following selector method in the same class.

class func profileBtnClicked(sender:UIButton) {
    print("Selected")
}

I've tried by removing class/static from the selector method, but it always give me unrecognized selector sent to instance error, where am I going wrong?

Thanks.

Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
Ibrahim Azhar Armar
  • 25,288
  • 35
  • 131
  • 207

3 Answers3

2
Try this 
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! ClinicListCell
    cell.title.text = clinicNames[indexPath.row]
    cell.subTitle.text = clinicSubs[indexPath.row]
    cell.backgroundImageView.image = UIImage(named: clinicImages[indexPath.row])
    cell.profileBtn.tag = indexPath.row
    cell.profileBtn.addTarget(self, action: #selector(YourViewController.profileBtnClicked(sender:)), for: UIControlEvents.touchUpInside)
    return cell
}


class func profileBtnClicked(sender:UIButton) {
    print("Selected")
}
Anil Kumar
  • 945
  • 7
  • 16
  • Thanks, this works. – Ibrahim Azhar Armar May 14 '17 at 14:00
  • 1
    Sorry, but the `class func` qualifier is wrong. You need an *instance* method or else you won't be able to access your view controller properties and methods. – Paulo Mattos May 14 '17 at 14:03
  • An answer is more helpful (to the author of the question and to future readers of this thread) if you *explain* the problem, instead of posting code only. What is wrong in OP's code and how is it fixed? – Martin R May 14 '17 at 14:16
1

Try adding a @objc to your method, not strictly required in this case, and remove the class or static qualifier.

By the way, since Swift 2.2, you can create a Selector from a Swift function using the #selector operator. For instance:

let clicked = #selector(self.profileBtnClicked(sender:))

for:

@objc func profileBtnClicked(sender: UIButton) {
    ...
}

Technically, for NSObject based classes, the @obj qualifier should only be required for private methods.

Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
1

Is the profileBtn linked up probably? This error may happens when the name has changed or the link between the button in interface builder and the variable is removed.

Or you can try with the syntax

cell.profileBtn.addTarget(self, action: #selector("profileBtnClicked:"), for: .touchUpInside)
Edison Lo
  • 476
  • 8
  • 25
  • If it was not linked up, it shouldn't throw me unrecognized selector error right? from the error what I understand is, it cannot find the selector method. – Ibrahim Azhar Armar May 14 '17 at 13:49