pdenlinger pdenlinger - 7 months ago 34
Swift Question

Checkmark won't toggle on/off

Have a checkmark in my tableview cells which won't toggle on or off. Can't figure out why. No matter how many times I press on the checkmark to check/uncheck it, it doesn't change state.

ChecklistViewController.swift

import UIKit

class ChecklistViewController: UITableViewController {

var items: [ChecklistItem]

required init?(coder aDecoder: NSCoder) {
items = [ChecklistItem]()

let row0item = ChecklistItem()
row0item.text = "Walk the dog"
row0item.checked = false
items.append(row0item)

let row1item = ChecklistItem()
row1item.text = "Brush my teeth"
row1item.checked = true
items.append(row1item)

let row2item = ChecklistItem()
row2item.text = "Learn iOS development"
row2item.checked = true
items.append(row2item)

let row3item = ChecklistItem()
row3item.text = "Soccer practice"
row3item.checked = false
items.append(row3item)

let row4item = ChecklistItem()
row4item.text = "Eat ice cream"
row4item.checked = true
items.append(row4item)

super.init(coder: aDecoder)
}


override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}

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

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

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("ChecklistItem", forIndexPath: indexPath)
let item = items[indexPath.row]
let label = cell.viewWithTag(1000) as! UILabel
label.text = item.text

configureTextForCell(cell, withChecklistItem: item)
configureCheckmarkForCell(cell, withChecklistItem: item)

return cell
}

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

if let cell = tableView.cellForRowAtIndexPath(indexPath) {
let item = items[indexPath.row]
item.checked = !item.checked

item.toggleChecked()
configureCheckmarkForCell(cell, withChecklistItem: item)
}

tableView.deselectRowAtIndexPath(indexPath, animated: true)
}

func configureCheckmarkForCell(cell: UITableViewCell, withChecklistItem item: ChecklistItem) {


if item.checked {
cell.accessoryType = .Checkmark
} else {
cell.accessoryType = .None
}


}

func configureTextForCell(cell: UITableViewCell, withChecklistItem item: ChecklistItem) {
let label = cell.viewWithTag(1000) as! UILabel
label.text = item.text
}

@IBAction func addItem() {
let newRowIndex = items.count

let item = ChecklistItem()
item.text = "I am a new row"
item.checked = false
items.append(item)

let indexPath = NSIndexPath(forRow: newRowIndex, inSection: 0)
let indexPaths = [indexPath]
tableView.insertRowsAtIndexPaths(indexPaths, withRowAnimation: .Automatic)
}


}


ChecklistItem.swift

import Foundation

class ChecklistItem {
var text = ""
var checked = false

func toggleChecked() {
checked = !checked
}
}

Answer

I think you have a typo inside tableView didSelectRowAtIndexPath

//1
item.checked = !item.checked //2
item.toggledChecked() //3
//4
  1. //lets say item.checked == true
  2. item.checked = !item.checked(false) // false
  3. toggleChecked -> item.checked = !item.checked //true
  4. //item.checked == item.checked at 1, no change

so you need to remove probably line 2.