Lastmboy
Lastmboy

Reputation: 1869

How can I use a switch in a tableview cell?

In iOS Swift 4.0 I have a switch in a tableview cell. However, whenever I tap it, it crashes with a unrecognized selector sent to instance message. I haven't been able to figure out a solution.

Here's how I have been trying to do it...

TableView Cell:

import UIKit

protocol PromoCellSubclassDelegate : class {
    func switchValueChanged(sender: UISwitch, cell: PromoCellSubclass)
}

class PromoCellSubclass: UITableViewCell {

    @IBOutlet weak var pageName: UILabel!
    @IBOutlet weak var activeSwitch: UISwitch!

    var delegate: PromoCellSubclassDelegate?

    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
    }

    override func prepareForReuse() {
        super.prepareForReuse()
        self.delegate = nil
    }

    @IBAction func ValueChanged(_ sender: UISwitch) {
        self.delegate?.switchValueChanged(sender: sender, cell: self)
    }
}

Parent ViewController:

class ProviderPromoViewController: Y2goViewController, UITableViewDelegate, UITableViewDataSource, PromoCellSubclassDelegate {

    @IBOutlet weak var tableView: UITableView!

...

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! PromoCellSubclass

    cell.delegate = self
    cell.pageName.text = promos[(indexPath as NSIndexPath).row].promoName
    cell.setBackground()

    let promoStatus = promos[(indexPath as NSIndexPath).row].statusCd!

    switch promoStatus {
    case 1:
        cell.activeSwitch.isOn = false
    case 2:
        cell.activeSwitch.isOn = true
    default:
        cell.activeSwitch.isOn = false
    }

    return cell
}

...


func switchValueChanged(sender: UISwitch, cell: PromoCellSubclass) {
    guard let indexPath = self.tableView.indexPath(for: cell) else {
        return
    }

    print("Switch changed on row \((indexPath as NSIndexPath).row)")
}

SwitchValueChanged is getting called and works properly, but it crashes as soon as it finishes. What did I miss?

Edit: The complete error message is:

2018-04-19 20:55:20.708538-0600 Y2GOsp[74562:15808974] -[Y2GOsp.PromoCellSubclass switchValueChanged:]: unrecognized selector sent to instance 0x7fd356838000 2018-04-19 20:55:53.253801-0600 Y2GOsp[74562:15808974] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Y2GOsp.PromoCellSubclass switchValueChanged:]: unrecognized selector sent to instance 0x7fd356838000'

Upvotes: 0

Views: 349

Answers (3)

Smitesh Wadher
Smitesh Wadher

Reputation: 156

Make sure that all the outlet connections are done properly, if not remove the connections and once again create the outlets.

I hope this could be of some help.

Upvotes: 0

Manish Mahajan
Manish Mahajan

Reputation: 2092

Why you used this class word in protocol declaration, there is no need of

protocol PromoCellSubclassDelegate : class {
    func switchValueChanged(sender: UISwitch, cell: PromoCellSubclass)
}

And what is this prepareForReuse, this is also not required..

override func prepareForReuse() {
    super.prepareForReuse()
    self.delegate = nil
}

Otherwise all code is right... Use Exceptional Breakpoint, debugger will stop where it crashing..

Upvotes: 0

trungduc
trungduc

Reputation: 12154

Clear your IBOutlet connections, connect them again and it will work ;)

Upvotes: 2

Related Questions