0

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?

rarora25
  • 99
  • 9
  • 1
    Are you trying to checkmark multiple rows or just one? It would be better to use your model or another property to store whether certain cell or cells are selected and set the checkmark in `cellForRowAt`, not `didSelectRowAt`. The problem you are currently getting is due to cell reuse. – rbaldwin May 21 '20 at 13:09

1 Answers1

3

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
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • how can I reset these cells to.none without deselecting, for example, when the user clicks on a cell then goes back- how can I reset all of these cells to .none – rarora25 May 21 '20 at 15:10
  • 1
    @rarora25 Again, you should update the model. For example, do `thingsSelectionStatuses = Array(repeating: false, count: listOfThings.count)` and then `tableView.reloadData()` to reload all the cells. – Sweeper May 21 '20 at 15:11