Search code examples
iosiphoneswiftuitableviewios9

How to use checkmark for UITableView


I am trying to create a simple todo list app for learning purposes i. I want to be able to click on a row and add a check mark and when clicked again i want it to go away. i have looked at several other examples but nothing is working. How can i achieve this?

class FirstViewController: UIViewController, UITableViewDelegate,         UITableViewDataSource {

@IBOutlet weak var tbView: UITableView!



override func viewDidLoad() {
    super.viewDidLoad()
    tbView.reloadData()
}
override func viewWillAppear(animated: Bool) {
    self.tbView.reloadData()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
    return tasks.manager.count
}

 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Default Tasks")

    //Assign the contents of our var "items" to the textLabel of each cell
    cell.textLabel!.text = tasks.manager[indexPath.row].name
    cell.detailTextLabel!.text = tasks.manager[indexPath.row].time

    return cell

}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath){

    if (editingStyle == UITableViewCellEditingStyle.Delete){

        tasks.manager.removeAtIndex(indexPath.row)
        tbView.reloadData()
    }
}

 func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let cell = tableView.cellForRowAtIndexPath(indexPath)
    cell!.accessoryType = .Checkmark
    tableView.reloadData()
}
}

Solution

  • To put it simply, you can use this code.

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        if let cell = tableView.cellForRowAtIndexPath(indexPath)
        if (cell!.accessoryType == .Checkmark) {
            cell!.accessoryType = .None
        } else {
            cell!.accessoryType = .Checkmark
        }
        tableView.reloadData()
    }
    

    This way, when you re-select cell, the checkmark will adjust accordingly.

    However, you shouldn't modify cell checkmark this way as the cell will get re used when you scroll. You need to update your data model instead it above approach.

    so in your data model, add new property to hold checkmark state and then use it in cellForRowAtIndexPath function.

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Default Tasks")
    
        //Assign the contents of our var "items" to the textLabel of each cell
        cell.textLabel!.text = tasks.manager[indexPath.row].name
        cell.detailTextLabel!.text = tasks.manager[indexPath.row].time
    
        if tasks.manager[indexPath.row].isSelected { //assume that isSelected is bool
            cell!.accessoryType = .Checkmark
        } else {
            cell!.accessoryType = .None
        }
    
        return cell
    }
    

    and then in your didSelectRowAtIndexPath update the model.

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let dataModel = tasks.manager[indexPath.row]
        dataModel.isSelected = !dataModel.isSelected
        tableView.reloadData()
    }