なんとかするから、なんとかなる

エンジニア関係のことを書きます

iOS UITableView deleteRows(at:with:) was crashed

Introdution

UITableView is one of the most popular UI system in iOS developer.

But, sometimes this UI system make us annoying.

In this time, when I try to delete the UITableViewCell from swipe or delete button, it would be crashed.

So, this article introduce how to handle this issue.

Probrem

When I wrote the code as below, it will be crashed.

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    guard editingStyle == .delete else { return }

    self.tableView.deleteRows(at: [indexPath], with: .fade) // Crashed
    
    // myArray is a DataSource to the tableView
    self.myArray.remove(at: indexPath.row)

An Error message said me as below.

 *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3698.54.4/UITableView.m:2012

Solution

After resolved the problem, it was simply mistake.

So, the deleteRow(at:with:) need to call after the datasource was changed.

The true code is below, it was working!

Developer need to take case of this kind of problem.

So, if the DataSource's remove method was failed, it will cause the same problem.

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    guard editingStyle == .delete else { return }

    // myArray is a DataSource to the tableView
    self.myArray.remove(at: indexPath.row)

    self.tableView.deleteRows(at: [indexPath], with: .fade) // Working!

Extra

The beginUpdates() and endUpdates() is need to call when the deleteRow(at:with:) would be working in the animation block.

So in this case, it's not need to call them.

Reference URL

https://developer.apple.com/documentation/uikit/uitableview/1614960-deleterows