Search code examples
swiftuitableviewuisearchbaraccessorytype

Checkmark's associated with wrong row in TableView when using SearchBar


I am creating an application where when a User searches for an item in the TableView they can click on it and a checkmark appears next to it. However, say when I select the first item I have searched for and click it then delete my search the checkmark stays on the first row but for a completely different object, I searched for, to begin with (see images below).

When Searching

When not Searching

var searchingArray = [Symptoms]()
var filteredArray = [Symptoms]()

var selectedSymptoms = [Symptoms]()

var clicked = [String]()

var searchingUnderWay = false

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    if let cell = searchingSymptomsTableView.dequeueReusableCell(withIdentifier: "ExtraSymptoms", for: indexPath) as? ExtraSymptomCell {

        let searchingArrays: Symptoms!

        if searchingUnderWay {

            searchingArrays = self.filteredArray[indexPath.row]


        } else {

            searchingArrays = self.searchingArray[indexPath.row]

        }

        cell.updateUI(symptomNames: searchingArrays)

        return cell

    } else {

        return UITableViewCell()
    }


}

  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    let selectedRow: Symptoms!

    let symptomName: String!

    let cell : UITableViewCell = tableView.cellForRow(at: indexPath)!

    if searchingUnderWay {

        selectedRow = filteredArray[indexPath.row]
        symptomName = filteredArray[indexPath.row].name as String

        if clicked.contains(symptomName) {

            cell.accessoryType = .none

            let indexNumber = clicked.index(of: symptomName)
            clicked.remove(at: indexNumber!)

            if let element = selectedSymptoms.index(where: { $0.name == selectedRow.name }) {

                selectedSymptoms.remove(at: element)
            }

        } else {

            clicked.append(symptomName)

            cell.accessoryType = .checkmark

            searchingSymptomsTableView.reloadData()

            selectedSymptoms.append(selectedRow)

        }



    } else {

        selectedRow = searchingArray[indexPath.row]
        symptomName = searchingArray[indexPath.row].name as String

        if clicked.contains(symptomName) {

            cell.accessoryType = .none

            let indexNumber = clicked.index(of: symptomName)
            clicked.remove(at: indexNumber!)

            if let element = selectedSymptoms.index(where: { $0.name == selectedRow.name }) {

                selectedSymptoms.remove(at: element)
            }

        } else {

            clicked.append(symptomName)

            cell.accessoryType = .checkmark

            searchingSymptomsTableView.reloadData()

            selectedSymptoms.append(selectedRow)

        }


        print(clicked)
        print(selectedSymptoms)



    }

}

I wish for the item I searched using the searchbar to still be checked when you delete the search.

Many thanks


Solution

  • Welcome to TableViewController logic. It seems really strange, but it works correct) You need to override prepareForReuse() method in your ExtraSymptomCell. And clear all the values your cell contains including accessoryType

    override func prepareForReuse() {
        super.prepareForReuse()
    
        accessoryType = .none
    }
    

    In your tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath):

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = searchingSymptomsTableView.dequeueReusableCell(withIdentifier: "ExtraSymptoms", for: indexPath) as? ExtraSymptomCell {
    
            let symptomName: String!
    
            let searchingArrays: Symptoms!
    
            if searchingUnderWay {
    
                searchingArrays = self.filteredArray[indexPath.row]
                symptomName = filteredArray[indexPath.row].name as String
    
            } else {
    
                searchingArrays = self.searchingArray[indexPath.row]
                symptomName = filteredArray[indexPath.row] as String
            }
    
            cell.updateUI(symptomNames: searchingArrays)
    
            if clicked.contains(symptomName)  {
                cell.accessoryType = .checkmark
            } else {
                cell.accessoryType = .none
            }
    
            return cell
    
        } else {
    
            return UITableViewCell()
        }
    }