import UIKit class ExistingLocationsViewController: UITableViewController { var oldRow = -1 // for state information var newRow = -1 // for state information var locationList: [LocationObject] = [ LocationObject(name: "name-1", address: "addr-1", phone: "phone-1", latitude: 40.0, longitude: -80.1), LocationObject(name: "name-2", address: "addr-2", phone: "phone-2", latitude: 40.0, longitude: -80.1) ] override func viewDidLoad() { super.viewDidLoad() // provides buffer space at the top so that the contents do not run into the top-margin (not needed if first cell is [intnetionally] blank) self.tableView.contentInset = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 0) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } override func numberOfSectionsInTableView(tableView: UITableView) -> Int { return 1 // QUESTION: I have two labels, but I consider it a single section - is that correct or should I be returning a value of '2' here? // If I make it '2', then the rows get duplicated (1, 2, 1, 2) and selecting row 2 does not automatically unselect row 1 } override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return locationList.count } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("resultCell", forIndexPath: indexPath) as! ExistingLocationTableViewCell let row = indexPath.row let item = locationList[row] cell.nameLabel.text = item.name cell.locationLabel.text = item.address let inval = cell.accessoryType.rawValue //#=# For debugging let insel = cell.selected //#=# For debugging if (cell.accessoryType == .Checkmark) || (cell.accessoryType.hashValue == 0) { cell.accessoryType = .None cell.selected = false } else { cell.accessoryType = .Checkmark cell.selected = true } let outval = cell.accessoryType.rawValue //#=# For debugging let outsel = cell.selected //#=# For debugging print("cellForRowAtIndexPath: (row = \(row))(oldRow = \(oldRow))(newRow = \(newRow))[selected: \(insel) => \(outsel)][actype: \(inval) => \(outval)]") //#=# return cell } override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) { let cell = tableView.dequeueReusableCellWithIdentifier("resultCell", forIndexPath: indexPath) as! ExistingLocationTableViewCell let insel = cell.selected //#=# For debugging let inval = cell.accessoryType.rawValue //#=# For debugging print("### didDeselectRowAtIndexPath => reloadRowsAtIndexPaths")//#=# self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None) let outsel = cell.selected //#=# For debugging let outval = cell.accessoryType.rawValue //#=# For debugging print("didDeselectRowAtIndexPath: (oldRow: \(oldRow))(newRow: \(newRow))[selected: (\(insel) => \(outsel))][accessory: (\(inval) => \(outval))")//#=# } override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { let cell = tableView.dequeueReusableCellWithIdentifier("resultCell", forIndexPath: indexPath) as! ExistingLocationTableViewCell newRow = indexPath.row let insel = cell.selected //#=# For debugging let inval = cell.accessoryType.rawValue //#=# For debugging let inrow = oldRow if newRow == oldRow { print("### didSelectRowAtIndexPath => didDeselectRowAtIndexPath")//#=# //self.tableView(tableView, didDeselectRowAtIndexPath: indexPath) //NOTE: Calling this and doing the reload and setSelected there seemed to not work as desired self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None) cell.accessoryType = .None // oldRow = -1 } else { if oldRow >= 0 { //# force deselection of old indexpath let oldIndexPath = NSIndexPath(forRow: oldRow, inSection: 1) self.tableView(tableView, didDeselectRowAtIndexPath: oldIndexPath) } print("### didSelectRowAtIndexPath => reloadRowsAtIndexPaths")//#=# self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None) cell.setSelected(true, animated: false) // Seems that this must be after call to reloadRowsAtIndexPaths oldRow = indexPath.row } let outsel = cell.selected //#=# For debugging let outval = cell.accessoryType.rawValue //#=# For debugging let outrow = oldRow //#=# For debugging print("didSelectRowAtIndexPath: (oldRow: (\(inrow) => \(outrow)))(newRow = \(newRow))[selected: (\(insel) => \(outsel)][accessory: (\(inval) => \(outval))")//#=# } }