0

I'm experiencing the following which I think has to do with something I'm missing when implementing tableView.dequeueReusableCell and how cells are being reused.

Expected behaviour:

  1. Select a cell and cell should change to green
  2. Scroll down
  3. Scroll back up and that selected cell is still green
  4. Scroll down and any unselected cell should not be green

Issue: when scrolling down, unselected cells are green (as if they've been selected). The following example shows the issue in step 7 and the last step.

Example

Below is my relevant code:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
                
        // Get a cell
        let cell = tableView.dequeueReusableCell(withIdentifier: "InstructionCell", for: indexPath) as! InstructionCell
        
        // Get the instruction that the tableView is asking about
        let instructionLabel = cell.instructionLabel
        
        if instructionLabel != nil {
            
            let currentArrayOne = arrayOne[currentArrayOneIndex!]
            
            if currentArrayOne.instructions != nil && indexPath.row < currentArrayOne.instructions!.count {
                // Set the instruction text for the instructionLabel
                instructionLabel!.text = currentArrayOne.instructions![indexPath.row]
            }
        }

        // Return the cell
        return cell

    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        let topInstruction = arrayOne[currentArrayOneIndex!].instructions![topInstructionIndex]
        print(topInstructionIndex)
        print(arrayOne[currentArrayOneIndex!].instructions!.count)
        
        // Check if it is the last instruction
        if topInstructionIndex < arrayOne[currentArrayOneIndex!].instructions!.count - 1 {
            
            // Change cell colour to green
            let tappedInstruction = tableView.cellForRow(at: indexPath)
            tappedInstruction?.contentView.backgroundColor =  #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1)
            
            topInstructionIndex += 1
            
            // Scroll to the next instruction
            let nextInstruction = IndexPath(row: topInstructionIndex, section: 0)
            tableView.scrollToRow(at: nextInstruction, at: UITableView.ScrollPosition.top, animated: true)
            return
            
        } else {
            // Show the lastInstruction dialog box
            if lastInstructionDialog != nil {
                
                present(lastInstructionDialog!, animated: true, completion: nil)
            }
            
            // Finish the instructions
            print("This is the last instruction.")
            return
        }

    }

I thought of adding override func prepareForReuse() within my custom InstructionCell class, but that resets those cells that have actually been selected as well. I need selected cells to remain selected (changed to green).

Any thoughts as to what I can change so that:

  1. Selected cells keep the changes of a selected cell (turn green) when scrolling in/out of view
  2. Unselected cells do not appear selected when scrolled into view

Any guidance is much appreciated!

amirbt17
  • 35
  • 5
  • You need to track cell selection in your data model and then set the appropriate cell appearance in `cellForRow(at:)` – Paulw11 Dec 30 '20 at 22:41

0 Answers0