2
votes

I have this tableView:

Image1

but I can't recognize when user selects the UISwitch in the row. I know I need an @IBAction in the UITableViewCell class but I didn't found a guide that works for me. I'd like to print the indexPath of the row when user clicks on the UISwitch.

This is my class for cell:

class TicketsFilterCell: UITableViewCell {


@IBOutlet weak var textFilter: UILabel!
@IBOutlet weak var switchFilter: UISwitch!


class var reuseIdentifier: String? {
    get {
        return "TicketsFilterCell"
    }
}

override func awakeFromNib() {
    super.awakeFromNib()
}

override func setSelected(selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

}

}

How can I do?

Thanks in advance.

Edit

My cellForRowAtIndexPath:

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

    let cell: TicketsFilterCell? = tableView.dequeueReusableCellWithIdentifier("cellTicketFilter", forIndexPath: indexPath) as? TicketsFilterCell

    cell?.delegate = self

    if(indexPath.section == 0) {

        let text = status[indexPath.row]?.capitalizedString

        cell?.textFilter.text = text


    } else if(indexPath.section == 1) {

        let text = queues [indexPath.row]?.capitalizedString

        cell?.textFilter.text = text

    } else if(indexPath.section == 2) {

        let text = types[indexPath.row]?.capitalizedString

        cell?.textFilter.text = text

    } else if(indexPath.section == 3) {

        let text = severities[indexPath.row]?.capitalizedString

        cell?.textFilter.text = text

    }



        return cell!

}
3
In the IBAction get the superview of the sender (switch) which is the table view cell. Then get the index path.vadian
@vadian Thanks you! I'll try this.Jigen

3 Answers

3
votes

Jigen,

Here is what you can do :)

Declare a protocol in your cell class lets call it as CellProtocol.

protocol CellProtocol : class {
    func switchButtonTapped(WithStatus status : Bool, ForCell myCell : TicketsFilterCell)
}

Declare a variable in your TicketsFilterCell class to hold delegate,

weak var delegate : CellProtocol!

When user taps on your switch trigger the delegate as

override func setSelected(selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)
    self.delegate .switchButtonTapped(WithStatus: selected, ForCell: self)
}

In your TableViewController confirm to protocol using

class ViewController: UITableViewController,CellProtocol {

Now in your ViewController's cellForRoAtIndexPath, for each cell set the delegate as self.

cell.delegate = self

Finally implement the delegate method as follow

func switchButtonTapped(WithStatus status: Bool, ForCell cell: TicketsFilterCell) {
        let indexPath = self.tableView .indexPathForCell(cell)
        print("cell at indexpath \(indexPath) tapped with switch status \(status)")
    }

EDIT :

For each cell you have dragged the IBOutlet for switch :) Now all you need is IBAction from UISwitch to the cell :)

@IBAction func switchTapped(sender: UISwitch) {
        self.delegate.switchButtonTapped(WithStatus: sender.on, ForCell: self)
    }

Thats it :)

1
votes

Use this

cell.yourSwitch.tag=indexPath.row;

in cellForRowAtIndexPath method

Based on that tag perform your code in switch on/off action.

1
votes

Add an @IBAction from the switch to the view controller itself. In the IBAction function convert the position of the sender(UISwitch) to tableView's frame. Then, find the cell at that point in tableView.

I believe this is the most elegant way to add actions to table view cells.

  • The biggest problem with the tag property is that its use always starts out simple, but over time the logic (or lack thereof) evolves into a fat unreadable mess.
  • This is easier than creating a protocol and implementing the delegate

Below is the IBAction connected to the switch's valueChanged action

@IBAction func switchValueChanged(sender: AnyObject) {
    let switchButton = sender as! UISwitch
    let buttonPosition = switchButton.convertPoint(CGPointZero, toView: self.tableView)
    let indexPath = self.tableView.indexPathForRowAtPoint(buttonPosition)!
    NSLog("switch at index %d changed value to %@", indexPath.row, switchButton.on)
}