I am trying to select a single cell for each section. Everything works fine but when I scroll tableview to the bottom or top the checkmark accessory appears on random cells. Here is the code:
tableView.allowsMultipleSelection = true
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
// Find any selected row in this section
if let selectedIndexPath = tableView.indexPathsForSelectedRows?.first(where: { $0.section == indexPath.section}) {
// Deselect the row
tableView.deselectRow(at: selectedIndexPath, animated: false)
// deselectRow doesn't fire the delegate method so need to
// unset the checkmark here
tableView.cellForRow(at: selectedIndexPath)?.accessoryType = .none
}
return indexPath
}
func tableView(_ tableView: UITableView, willDeselectRowAt indexPath: IndexPath) -> IndexPath? {
// Prevent deselection of a cell
return nil
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
}
any help would be appreciated to avoid this
2
Answers
That is happening because you are making changes to on-screen cells without updating your model to reflect those changes. Then when a cell gets recycled, sometimes you pick up a cell that still has it’s checkmark set.
Don’t reach into cells and change their appearance. Instead, mark the cell as needing to be updated (by calling
reloadRows(at:with)
) and then in yourtableView(cellForRowAt:)
method, always set the accessory type to either.none
or.checkmark
.This happens because cells are reusable. I don’t think its a good idea to call
tableView.cellForRow
indidSelectRowAt
.You must control which indexPath are selected incellForRowAt
Try this :
And in your
cellForRowAt