iosswiftselectioncheckmark

Swift: Trouble with Accessories


in my project I was just adding this line of code to add a little checkmark next to the cell that the user selects. (In did select row at function)

    let currentCell = tblView.cellForRow(at: indexPath)! as UITableViewCell
    currentCell.accessoryType = .checkmark

The currentCell is printing fine. For example, when I print out the cell, it gives me the cell's frame; text; clipsToBounds; autoresize; layer:0>. When I add this line of code though, as expected, it does add check mark on that cell, but also every other 15 cells, starting from that cell- and it looks like this every fifteen cells have a check

Does anyone know why this is happening, and how I could fix this?


Solution

  • That's not how you use a table view.

    Table view cells are reused. The checkmark appeared on a cell you didn't tap on because that actually the same UITableViewCell object as a cell that you did tap on, but since that cell has been scrolled out of view, it is re-displayed again at the bottom, just with a different label text.

    The correct thing to do in didSelectRow is to update your model. Right now, you are probably using an array of things as the data source of the table view:

    var listOfThings: [MyModel]!
    

    Now you just need to also store which things are selected and which are not in your model, in some way or another. E.g. in another array:

    var thingsSelectionStatuses: [Bool]!
    

    Initialise it like this:

    thingsSelectionStatuses = Array(repeating: false, count: listOfThings.count)
    

    In didSelectRow, update thingsSelectionStatuses and reload the cell.

    thingsSelectionStatuses[indexPath.row].toggle()
    tableView.reloadRows(at: [indexPath], with: .automatic)
    

    Reloading the cell will lead to cellForRowAt being called. In cellForRowAt, we set the accessoryType depending on thingsSelectionStatuses:

    cell.accessoryType = thingsSelectionStatuses[indexPath.row] ? .checkmark : .none