swiftuitableviewcheckmark

Tableview checkmark wrong place


I tried like so to add checkMark on cell but if I tap section 0 row 0, section 2 row 0 also checked. Also if tap section 0 row 1, section 3 row 0 checked(vise verse if I tap section 2 row 0, section 0 row 0 also checked also if tap section 3 row 0, section 0 row 1 checked).

And if scrolling fast all check goes away. How can I fix this? Thank you in advance!

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

        @IBOutlet var tableView: UITableView!

        var sectionName = ["Cars", "Motor Cycles", "EV", "Hybrid"]
        var cars = ["TOYOTA", "AUDI", "BMW", "HONDA", "VOLVO", "VW","FIAT"]
        var motorCycles = ["YAMAHA", "HONDA", "DUCATI", "HARLEY DAVIDSON", "VICTORY"]
        var yes = "YES"

        override func viewDidLoad() {
            super.viewDidLoad()

            tableView.dataSource = self
            tableView.delegate = self

        }



        func numberOfSections(in tableView: UITableView) -> Int {
            return sectionName.count
        }

        func tableView(_ tableView: UITableView,titleForHeaderInSection section: Int) -> String? {
            return sectionName[section]
        }

        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

            if section == 0 {
                return cars.count
            } else if section == 1 {
                return motorCycles.count
            } else {
                return 1
            }

        }

        let cellId = "cell"

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

            let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
            let section = indexPath.section

            if section == 0 {
                cell.textLabel?.text = cars[indexPath.row]
            } else if section == 1 {
                cell.textLabel?.text = motorCycles[indexPath.row]
            } else {
                cell.textLabel?.text = yes
            }

            return cell
        }

        var firstArray = [String?]()
        var secondArray = [String?]()
        var thirdString = ""
        var fourthString = ""

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

            let currentCell = tableView.cellForRow(at: indexPath)
            let section = indexPath.section
            let text = currentCell!.textLabel!.text!

            if currentCell?.accessoryType == .checkmark {

                switch section {

                case 0:
                    firstArray = firstArray.filter( { $0 != text } )
                    currentCell?.accessoryType = .none
                case 1:
                    secondArray = secondArray.filter( { $0 != text } )
                    currentCell?.accessoryType = .none

                case 2:
                    thirdString = ""
                    currentCell?.accessoryType = .none

                case 3:
                    fourthString = ""
                    currentCell?.accessoryType = .none

                default:
                    break

                }

            } else {

                switch section {

                case 0:
                    firstArray.append(text)
                    currentCell?.accessoryType = .checkmark
                case 1:
                    secondArray.append(text)
                    currentCell?.accessoryType = .checkmark

                case 2:
                    thirdString = text
                    currentCell?.accessoryType = .checkmark
                case 3:
                    thirdString = text
                    currentCell?.accessoryType = .checkmark

                default:
                    break

                }
            }
        }
    }

Solution

  • A better way is to put checkMark setting logic inside cellForRow , as because of dequeuing un wanted cells may get checked , so in didSelectRow store Indexpath/s of one/s you want to check and reload the cell with the selected IndexPath