Swifter
Swifter

Reputation: 73

How to save checkmark state in a UITableView for Core Data App in Swift

I have implemented a list application using Core Data.What I wanted to do is add checkmarks so the user can click on a cell and a tick would show up to show it is completed.

I don't know how to save these checkmarks so when the app is closed and opened or restarted the check will still be there on the specific cell. Should I implement this with CoreData or NSUserDefaults? How would I go about implementing it using these?

Here is the code so far:

cellForRowAtIndex :

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell")! as UITableViewCell
    let item = Items[indexPath.row]
    cell.textLabel?.item = task.valueForKey("item") as? String

    return cell
}

DidSelectRowAtIndex:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {


    let selectedRow:UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!

    if selectedRow.accessoryType == UITableViewCellAccessoryType.None {

        selectedRow.accessoryType = UITableViewCellAccessoryType.Checkmark

        selectedRow.tintColor = UIColor.greenColor()

    } else {

        selectedRow.accessoryType = UITableViewCellAccessoryType.None

    } 
} 

Any help will be appreciated.

Upvotes: 0

Views: 2304

Answers (1)

Paulw11
Paulw11

Reputation: 115083

You need to track the completion status in your data model (The Core Data objects) not the cells. Cells are re-used as you have found, also cells aren't persisted, so the checkmark state isn't saved.

I would use something like this:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    let taskObject=self.listItems[indexPath.row]
    var taskStatus = taskObject.valueForKey("completed") as? Bool ?? false

    taskObject.setValue(!taskStatus,forKey:"completed") // Toggle completed status

    do {
        try managedContext.save()
    } catch let error as NSError {
        print("Cannot save object: \(error), \(error.localizedDescription)")
    }

    tableView.deselectRowAtIndexPath(indexPath,animated:false)

    tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
}

Then, in your cellForRowAtIndexPath you can render the row appropriately:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("listCell") as! UITableViewCell
    let task = listItems[indexPath.row]
    let taskStatus = task.valueForKey("completed") as! Bool
    cell.textLabel?.text = task.valueForKey("task") as? String

    var accessoryType=UITableViewCellAccessoryType.None
    var tintColor = UIColor.clearColor()

    if (taskStatus) {
         accessoryType=UITableViewCellAccessoryType.Checkmark
         tintColor = UIColor.greenColor()
    }

    cell.accessoryType=accessoryType
    cell.tintColor = tintColor

    return cell
}

Upvotes: 2

Related Questions