1

When selecting and deselecting a record found in a tableView cell I have a checkmark accessory appear.

I am doing so as the following:

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

The issue is it always takes two taps to deselect the checkmark if the record already exists when the tableView is first loaded.

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

The tableView is based on JSON with the following structure:

var structure = [JSONStructure]()

struct JSONStructure: Codable {
    var peron: String
    var update: Int
}

If update is has a value of 100 a checkmark is applied if the value is a 200 no checkmark is applied.

This is done in cellForRowAt as the following:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let TableInfo: JSONStructure

if (TableInfo.update == 100) {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
  }
}

When the tableView first loads and a checkmark already exist because the update criteria is met, how can I prevent having to double press to unselect the record?

John
  • 965
  • 8
  • 16

2 Answers2

0
    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
        let cell = tableView.cellForRow(at: indexPath) 
            cell.accessoryType = .none

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


    }
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("cellData", forIndexPath: indexPath) 
    if (TableInfo.update == 100)
        cell.accessoryType = .Checkmark
        tableView.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: UITableViewScrollPosition.Bottom)
    } else {
        cell.accessoryType = .None
    }

    return cell
}
ArunPrasath
  • 150
  • 5
0

Your cellForRowAt only marks the Cell visually (setting accessoryType), but you need to mark it as checked for the UITableView logic too. Implement willDisplay on your delegate and update the selected state there. Example:

 func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
  // .. get TableInfo for indexPath.row
  let TableInfo: JSONStructure

  if (TableInfo.update == 100) {
    tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableView.ScrollPosition.none)
  } else {
    tableView.deselectRow(at: indexPath, animated: false)
  }
}

See f.e. UITableViewCell Set selected initially although some of the options differ in wether cellForRowAt or willDisplayCell is used.

See iOS UITableView: what's the different between "cellForRowAtIndexPath" and "willDisplayCell: forRowAtIndexPath:" on why to use willDisplay vs. cellForRowAt for the selection.

makadev
  • 1,034
  • 15
  • 26
  • I appreciate your help, I think you may have a typo, I get the error `Extra argument 'scrollPosition' in call` – John Aug 28 '19 at 16:23
  • Fixed, copy and paste is bad and so on. – makadev Aug 28 '19 at 16:29
  • Now I get the error Constant 'TableInfo' used before being initialized. This doesn't make sense to me since it is defined right above the conditional – John Aug 28 '19 at 16:37
  • Yes, it is uninitialized. Thats from the code you wrote in your Question. You probably need to set `let TableInfo: JSONStructure = structure[indexPath.row]` if `structure` is your data for the table. – makadev Aug 28 '19 at 16:43