Renan Lopes
Renan Lopes

Reputation: 1480

Swift 5 | didSelectRowAt is selecting two cells at the same time

I am doing a screen where there a list o cells with a switch, like an image below; I have a struct where a save the label of the cell and the switch state value. This struct is loaded at: var source: [StructName] = [] and then source values are attributed to the UITableView cells.

The problem is that when a touch a cell the function: func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) change multiples cells switches states at the same time. I try to work around the problem by implementing the following function:

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)

    let cell = tableView.cellForRow(at: indexPath) as! CustomTableViewCell
    for n in 0..<source.count{ // This loop search for the right cell by looking at the cell label text and the struct where the state of the switch is saved
        if cell.label.text! == source[n].Label{
            // If the label text is equal to the position where the values is saved (is the same order that the cells are loaded in the UITableView) then a change the state of the switch
            let indexLabel = IndexPath(row: n, section: 0)
            let cellValues = tableView.cellForRow(at: indexLabel) as! CustomTableViewCell
            if cellValues.switchButton.isOn {
                cellValues.switchButton.setOn(false, animated: true)
                source[n].valor = cellValues.switchButton.isOn
            } else {
                cellValues.switchButton.setOn(true, animated: true)
                source[n].valor = cellValues.switchButton.isOn
            }
            break
        }
    }

although is saved the right values to the switch state array(source) the visual state of multiples switches also changes even though the cells where never touch.

How could I change my code to select and change only the touched cell?

enter image description here

Upvotes: 0

Views: 791

Answers (1)

Andreas Oetjen
Andreas Oetjen

Reputation: 10209

You should not store / read the state of anything in a cell. But first things first:

  • Why do loop through all the values? You should be able to access the row in the data model directly by indexPath.row
  • You should only modify the model data, not the cell
  • You then tell the table view to reload the cell, which will then ask the model for the correct data to be displayed.

I would suggest the following:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)

    let row = indexPath.row
    source[row].valor.toggle()
    tableView.reloadRows(at:[indexPath], with:.automatic)
}

Upvotes: 3

Related Questions