1

UITableView allows you to assign an accessory -- like a button -- that shows on the right side of the cell (documentation).

In my audio app, I will want to allow a user to download by clicking the accessory and then show it succeeded with a checkmark. To test this now, I just want the accessory detail to turn into a checkmark after it's tapped.

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

    cell.textLabel?.text = TableData[indexPath.row]

// this works, adds a button to right cell 
    cell.accessoryType = .detailDisclosureButton

    return cell
}

override func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
    // doSomethingWithItem(indexPath.row)

   // my logic: this function applies when button is tapped. I try to reset the accessory type to checkmark when clicked 
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

    cell.accessoryType = .checkmark

}

This will build, but it results in a failure starting with *** Assertion failure in -[UITableView _dequeueReusableCellWithIdentifier:forIndexPath:usingPresentationValues:],

I'm new to Swift, but this seemed logical: set a function to take an action when the accessory is clicked and then set the accessory to a checkmark (one of the accessory types).

Is there a better way to do this?

A note: I do not want to use a segue or move to a different VC; I'd like this to update the UI within the table view.

darkginger
  • 652
  • 1
  • 10
  • 38
  • https://stackoverflow.com/questions/12737860/assertion-failure-in-dequeuereusablecellwithidentifierforindexpath – Amit Jan 20 '18 at 06:36

1 Answers1

2

Instead of using dequeReusableCell you should be using cellForRow in your accessoryButtonTappedForRow function.

Read the documentation to see the difference between those two functions and look a little further into how cell reuse works. cellForRow(at:) returns the specific UITableViewCell, which is what you are looking for in this situation.

override func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
  // doSomethingWithItem(indexPath.row)

  // cellForRow instead of dequeue
  let cell = tableView.cellForRow(at: indexPath)

  cell.accessoryType = .checkmark

}

In addition, make sure you are registering your cell with that same reuse identifier of "cell" with either registerClass or registerNib

Kayla Galway
  • 662
  • 4
  • 7
  • Thank you, Kayla. If you want to update your answer, the modification I used: `let cell = tableView.cellForRow(at: indexPath)` and it runs! – darkginger Jan 20 '18 at 06:49