Search code examples
swiftuibuttonnsindexpath

Error: Index Path on a UIButton (Swift)


I'm able to successfully append a phone number into the phoneNumbers array but when I try yo use indexPath, I get an error saying: "unrecognized selector sent to instance." Does this mean I can't use indexPath with the callButton function? If so, what alternative can I do?

   override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("MyCell") as! TableViewCell
    cell.callButton.addTarget(self, action: "callButton", forControlEvents: UIControlEvents.TouchUpInside)
    return cell

}

func callButton(indexPath: NSIndexPath) {

    UIApplication.sharedApplication().openURL(NSURL(string: "telprompt://\(phoneNumbers[indexPath.row])")!)

}

Solution

  • Your error comes because after you have set you @IBAction using Interface Builder and its was registered as its target, you have changed its signature and added arguments and this make the unrecognized selector sent to instance.

    Once you have define your IBOutlet for your UIButoon in your custom cell class, you can access and set anything you want for the class in your cellForRowAtIndexPath, like in the following way:

    CustomTableViewCell

    import UIKit
    
    class TableViewCell: UITableViewCell {
    
       @IBOutlet weak var button: UIButton!
    
       var phoneNumber: Int!
    
       override func awakeFromNib() {
          super.awakeFromNib()
          // Initialization code
       }
    
       override func setSelected(selected: Bool, animated: Bool) {
           super.setSelected(selected, animated: animated)
    
           // Configure the view for the selected state
       }
    
       @IBAction func callButton(sender: AnyObject) {
          println("Calling to \(self.phoneNumber)")
       }
    }
    

    And then in your UITableViewController or UIViewController you can set what do you want for your UIButton like in the following code:

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! TableViewCell
    
        // Set the phone number according the indexPath.row of the cell to call later
        cell.phoneNumber = self.phoneNumberList[indexPath.row]
    
        return cell
    }
    

    When you set the phoneNumber in the cellForRowAtIndexPath you're setting for each cell a different phoneNumber, it's the point of doing this inside the cellForRowAtIndexPath.

    I hope this help you.