I know there's a number of posts on this subject and I've been through most of them but I still can't solve an issue I'm having when deleting a tableViewCell causing my app to crash with the follow error:
Assertion failure in -[UITableViewRowData rectForRow:inSection:heightCanBeGuessed:]
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'request for rect at invalid index path (<NSIndexPath: 0xc000000000000016> {length = 2, path = 0 - 0})'
I explicitly set the height of my rows using
tableView.rowHeight = 140
My code for the delete is as follows
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let deleteAction = UITableViewRowAction(style: .destructive, title: "Delete") { (action, indexPath) in
let object = self.datastore[indexPath.row]
do {
try self.realm?.write {
self.realm?.delete(object)
self.datastore.remove(at: indexPath.row)
self.tableView.deleteRows(at: [indexPath], with: .none)
}
} catch let error {
}
}
deleteAction.backgroundColor = .red
return [deleteAction]
}
This does delete the item correctly from the dataStore. I've tried a number of different solutions here such as calling the delete on the mainThread, reloading the whole dataSource etc. but it still crashes.
My numberOfRowsInSection
method gets called and is return the correct number of rows after the deletion so that doesn't appear to be the issue.
Adding a general exception breakpoint though I think it's crashing here
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as? Cell {
cell.image.kf.cancelDownloadTask()
}
}
kf here is the kingfisher library as I want to cancel an image download if the cell is removed
What I have noticed is that if I use
`tableView.dequeueReusableCell(withIdentifier: "Cell")`
instead of
tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
This doesn't crash, so that might be my solution, but I'm eager to understand what's wrong here. I understand that the 'forIndexPath' method should always return a cell but in this instance is crashing because of a nil.
I have the same deletion code in another viewController that doesn't rely on the didEndDisplaying:Cell method and this doesn't crash
You need to change this line in didEndDisplaying. you need to get existing cell.
let cell = tableView.cellForRowAtIndexPath(indexPath)