UITableview delete swipe action

A delete row action that works in iOS 10 crashes when run in iOS 11 beta 2. The crash is because after the UITableViewRowAction closure runs the number of rows count is incorrect. IOS 11 BETA 2 RELEASE NOTES say The behavior of the delete swipe action has been changed.When implementing commitEditingStyle: to delete a swiped row, delete the row in the data source and call deleteRowsAtIndexPaths: on the table view to show the swipe delete animation. Not calling deleteRowsAtIndexPaths inside of this method results in the swiped row resetting to its resting position. My delete action does call deleteRows(at: , with:). I can't seem to find any further clarification. Does anyone have any information or can send me in the right direction?

Answered by bbousquet in 243014022

I had the same issue:


    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            tableView.beginUpdates()
            tableView.deleteRows(at: [indexPath], with: .automatic)
            switch indexPath.section {
            case 0:
                // remove from data model
                // ...
            case 1:
                // remove from data model
                // ...
            default:
                break
            }
            tableView.endUpdates()
        }
    }


It seems the model changes must be made prior to calling deleteRows, regardless of the fact we're in an update "block". Fixed version that no longer asserts:


    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            tableView.beginUpdates()
            switch indexPath.section {
            case 0:
                // remove from data model
                // ...
                tableView.deleteRows(at: [indexPath], with: .automatic)
            case 1:
                // remove from data model
                // ...
                tableView.deleteRows(at: [indexPath], with: .automatic)
            default:
                break
            }
            tableView.endUpdates()
        }
    }

I am also having this problem. Infact, current app store version of my app is also crashing on iOS 11 when a row is deleted.


Not calling deleteRowsAtIndexPaths: inside ...commitEditingStyle:... fixes the crash but without delete animation.

I have fixed it partly by calling reloadSections([indexPath], with: .automatic) but when I delete some row the minus button appears on the right side of all the rows and I cannot get rid of it. Have anybody found the same issue?

Accepted Answer

I had the same issue:


    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            tableView.beginUpdates()
            tableView.deleteRows(at: [indexPath], with: .automatic)
            switch indexPath.section {
            case 0:
                // remove from data model
                // ...
            case 1:
                // remove from data model
                // ...
            default:
                break
            }
            tableView.endUpdates()
        }
    }


It seems the model changes must be made prior to calling deleteRows, regardless of the fact we're in an update "block". Fixed version that no longer asserts:


    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            tableView.beginUpdates()
            switch indexPath.section {
            case 0:
                // remove from data model
                // ...
                tableView.deleteRows(at: [indexPath], with: .automatic)
            case 1:
                // remove from data model
                // ...
                tableView.deleteRows(at: [indexPath], with: .automatic)
            default:
                break
            }
            tableView.endUpdates()
        }
    }

Thanks bbousquet. Re-ordering the action so the deleteRows(at:with:) occurs last solved the issue.

It has been fixed in iOS 11.2

UITableview delete swipe action
 
 
Q