swiftuitableviewuitableviewrowaction

UITableViewCell missing deletion control after successive left-swipes


I use a tableview with editable custom style cells. There's an Edit button in the navigation bar which toggles editing mode. I need the editing mode to delete and reorder rows.

When I left-swipe a cell, the Delete action button shows on the right side of that cell. While it is displayed, I press the Edit button and the Delete action button disappears. Pressing the Edit button again shows the deletion command left and the reordering controls right of ALL(!) cells. So far all as expected.

Now (as an example), when I left-swipe cell 0, then left-swipe cell 1 while Delete action button in cell 0 is still visible, activating editing mode with Edit button now shows deletion command left and reordering control right of all cells, EXCEPT(!) cell 0.

I found out that as soon as 2 or more cells are left-wiped, the first cell which is not right-swiped back out of editing mode, misses the deletion control (left) when editing mode for all cells is enabled using Edit button. Even more weird ... on subject cell missing deletion control (left), the reordering control (right) shows correctly!

I followed and compared many tutorials but didn't catch the error.

What do I miss?

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    ...
}

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

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    ...
}

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    ...
}

override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
    ...
}

override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
    ...
}

// not necessary = didn't change anything, but found in many tutorials
override func setEditing(_ editing: Bool, animated: Bool) {
    super.setEditing(editing, animated: animated)
}

@IBAction func editAction(_ sender: Any) { // that's the Edit button action
    self.setEditing(!isEditing, animated: true)
    self.navigationItem.leftBarButtonItem?.title = isEditing ? "Done" : "Edit"
}

Above all involved methods. Irrelevant method content is omitted to keep the post compact. I will add/edit if deemed required.

screenshot 1
View after left-swipe of cell 1 (disregard Rename and Share actions).

screenshot 2
View after left-swipe of cell 2, then cell 1, then entering editing mode using Edit button.


Solution

  • I found the reason for the misbehaviour. Since I use animation in the setEditing() method, I need to to tell the view that there are updates using beginUpdates() and endUpdates(). That did the job! No badly displayed cells anymore neither simulator, nor device!

    @IBAction func editAction(_ sender: Any) {
        tableView.beginUpdates()
        self.setEditing(!isEditing, animated: true)
        tableView.endUpdates()
        self.navigationItem.leftBarButtonItem?.title = isEditing ? "Done" : "Edit"
    }
    

    EDIT 1

    Above (beginUpdates() and endUpdates()) works as desired, but below (performBatchUpdates {}) is more modern (iOS 11.0) and should be preferred.

    @IBAction func editAction(_ sender: Any) {
        tableView.performBatchUpdates {
            self.setEditing(!isEditing, animated: true)
        }
        self.navigationItem.leftBarButtonItem?.title = isEditing ? "Done" : "Edit"
    }
    

    EDIT 2

    Meanwhile I believe that the OP misbehaviour is an iOS bug.

    By chance, I found that the Safari Bookmarks tableview behaves the same way. Left-swipe cell 0, then left-swipe cell 1, next press Done/Edit button (lower right corner) twice. You can observe that cell 0 doesn't show the deletion control icon (one-way-sign) left side of cell 0. Consequently I believe this is a iOS bug.

    Besides this, other apps produce the same misbehaviour on editing tableviews.