Home > front end >  Issue with selecting single cell for each section
Issue with selecting single cell for each section

Time:01-07

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

CodePudding user response:

This happens because cells are reusable. I don't think its a good idea to call tableView.cellForRow in didSelectRowAt.You must control which indexPath are selected in cellForRowAt

Try this :

 var selectedRows = [IndexPath]() // selected indexPaths array
   func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if selectedRows.contains(indexPath){ // if already selected , remove
        selectedRows = selectedRows.filter({$0 != indexPath})
    }else{
        selectedRows.append(indexPath)
    }
    tableView.reloadRows(at: [indexPath], with: .automatic)
  }

And in your cellForRowAt

  if selectedRows.contains(indexPath){
        cell.accessoryType = .checkmark
    }else{
        cell.accessoryType = .none
    }

CodePudding user response:

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 your tableView(cellForRowAt:) method, always set the accessory type to either .none or .checkmark.

  •  Tags:  
  • Related