Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dismiss swipe action context menu on cancel

I've added a swipe to delete functionality with the use of

override func tableView(_ tableView: UITableView, 
        trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) 
         -> UISwipeActionsConfiguration?

I'm calling an alert with dismiss/confirm actions. Once dismissed I want to dismiss the swipe action menu.

    override func tableView(_ tableView: UITableView,
                            trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {

        let deleteClosure:UIContextualAction.Handler = {
            (action:UIContextualAction,
            view:UIView,
            completionHandler:(Bool) -> Void) in
            let alert = self.confirmDeletion({ _ in

                let row = indexPath.row;
                let removed = self.logList.remove(at: row);
                self.deleteLogEntry(removed);
                //
                tableView.reloadData();
                //

            }, declineBlock: {_ in
                tableView.reloadData();// this hides it but w/o animation
            });
            DispatchQueue.main.async {
                self.present(alert, animated: true, completion: nil);
            }
        }
        let deleteAction = UIContextualAction(style: .destructive, title: "Delete", handler: deleteClosure);

        return UISwipeActionsConfiguration(actions: [deleteAction]);
    }

So far I've found that reloading table data will close the trailing swipe menu but w/o animation which looks odd. Is there a way to tell it to dismiss with an animation?

** Note about duplicate ** Marked as duplicate to the question that refers to dismiss not working as expected AFTER row was deleted, it is not the case here. I want to dismiss trailing swipe when user cancels deleting and row is NOT removed.


What I've already tried:

  • tableView.setEditing(false, animated: true); - no visible difference
  • tableView.reloadRows(at: [indexPath], with: UITableView.RowAnimation.automatic); - row was moved right with animation but the button was overlapping
  • tableView.resignFirstResponder(); - no visible difference (I had to try)
  • tableView.reloadTable() - swipe menu IS dismissed but w/o animation effect
like image 994
Lukasz 'Severiaan' Grela Avatar asked Nov 23 '25 12:11

Lukasz 'Severiaan' Grela


1 Answers

You need to call the completionHandler with the result to dismiss the swipe action. Here is the help on the UIContextualActionHandler;

// call the completionHandler to reset the context to its normal state (e.g. when swiping, resets to unswiped state)
// pass YES to the completionHandler if the action was actually performed, to show a visual indication of the successful completion
typedef void (^UIContextualActionHandler)(UIContextualAction *action, __kindof UIView *sourceView, void(^completionHandler)(BOOL actionPerformed));
like image 172
Suman C Avatar answered Nov 25 '25 09:11

Suman C