iosswifttableviewviewcontrollercheckmark

Save the state of checkmarked cell in table view in swift 4.2


I have made a table view in a view controller and populating it programmatically. I am able to checkmark on cell at a time as i wanted but when i come back to that screen, it is not there.

These are my arrays:

let devCourses = [("Sound"),("Vibrate"),("Both"),("None")]

let devCousesImages = [UIImage(named: "speaker"), UIImage(named: "Group 1094"), UIImage(named: "Group 1093"), UIImage(named: "speaker-1")]

Here is my code for didSelectRowAt:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark

    }

Here is the code for didDeselectRowAt:

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
        tableView.cellForRow(at: indexPath)?.accessoryType = .none
    }



func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell=tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath as IndexPath) as! VibTableViewCell

        let courseTitle = devCourses[indexPath .row]

        let Images = devCousesImages[indexPath .row]

        cell.label.text=courseTitle
        cell.label.textColor = UIColor.darkGray
        cell.photo.image=Images

        return cell
    }

I want the checkmark to be there when i get back to the screen


Solution

  • You can use my solution.

    Save state of your cells in plist file with NSCoder. Even you restart your app - you don't lose your data.

    import UIKit
    
    class TableViewController: UITableViewController {
    
        var itemsArray : [Item] = [Item(name: "mom", done: true), Item(name: "pap", done: false), Item(name: "Lena", done: false), Item(name: "Gleb", done: false), Item(name: "Sasha", done: false), Item(name: "Max", done: false)]
    
    
        /* path to custom plist file */
        let dataFilePath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("Items.plist")
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            if let filePath = dataFilePath {
                print(filePath)
            }
    
            loadData()
        }
    
        // MARK: - Table view data source
    
        override func numberOfSections(in tableView: UITableView) -> Int {
            // #warning Incomplete implementation, return the number of sections
            return 1
        }
    
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            // #warning Incomplete implementation, return the number of rows
            return itemsArray.count
        }
    
    
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
            let item = itemsArray[indexPath.row]
            cell.accessoryType = item.done ? .checkmark : .none
            cell.textLabel?.text = item.name
            // Configure the cell...
    
            return cell
        }
    
        override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    
            itemsArray[indexPath.row].done = !itemsArray[indexPath.row].done
    
            /* when state is changed - save it to plist file */
            saveDate()
    
            tableView.deselectRow(at: indexPath, animated: true)
        }
    
    
        /* save array to plist file (you can see it inside folder from consol) */
        func saveDate() {
            let encoder = PropertyListEncoder()
            do {
                let data = try encoder.encode(itemsArray)
                try data.write(to: dataFilePath!)
            } catch {
                print(error.localizedDescription)
            }
            self.tableView.reloadData()
        }
    
    
        /* load data from plist file */
        func loadData() {
    
            if let data = try? Data(contentsOf: dataFilePath!) {
                let decoder = PropertyListDecoder()
                do {
                    itemsArray = try decoder.decode([Item].self, from: data)
                } catch {
                    print(error.localizedDescription)
                }
            }
    
        }
    }
    

    dataModel:

    import Foundation
    
    struct Item : Encodable, Decodable {
        var name : String = ""
        var done : Bool = false
    }