Как отключить контекстное меню действия салфетки при отмене

#ios #swift #uitableview #uiswipeactionsconfiguration

#iOS #swift #uitableview #uiswipeactionsconfiguration

Вопрос:

Я добавил функцию салфетки для удаления с использованием

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

Я вызываю оповещение с отклонением / подтверждением действий. После отклонения я хочу отклонить меню действия салфетки.

     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]);
    }
  

До сих пор я обнаружил, что перезагрузка табличных данных закроет завершающее меню салфетки, но без анимации, которая выглядит странно. Есть ли способ сообщить ему об отмене с помощью анимации?

** Примечание о дубликате ** Помечено как дубликат вопроса, который ссылается на то, что отклонение не работает должным образом ПОСЛЕ удаления строки, здесь это не так. Я хочу отклонить завершающий свайп, когда пользователь отменяет удаление, а строка НЕ удаляется.


Что я уже пробовал:

  • tableView.setEditing(false, animated: true); — нет видимой разницы
  • tableView.reloadRows(at: [indexPath], with: UITableView.RowAnimation.automatic); — строка была перемещена вправо с анимацией, но кнопка перекрывалась
  • tableView.resignFirstResponder(); — нет видимой разницы (я должен был попробовать)
  • tableView.reloadTable() — меню салфетки отключено, но без эффекта анимации

Комментарии:

1. Я не использовал UIContextualAction, но с более старым вариантом UITableViewRowAction я бы назвал TableView.setEditing(false, animated: true)

2. Это не работает, я пробовал это, я обновлю вопрос тем, что я пробовал, и результатами (сбоями).

3. Как указывает @rmaddy, это похоже на дубликат. Смотрите второй ответ в связанном вопросе. Обработчик завершения должен вызываться с false в вашем случае как отмененный пользователем (и true если удаление не отменено).

4. Кто-нибудь из вас пробовал это, по крайней мере, прежде чем говорить что-либо о дублировании? Вызов обработчика завершения с false отключит меню салфетки, как только пользователь нажмет на удаление, ПРЕЖДЕ чем оповещение запросит подтверждение. Как я уже неоднократно говорил, это не тот же вопрос.

5. Похоже, вы не можете успешно запросить пользователя подтвердить удаление, и Apple, похоже, не реализует это в приложении Notes, поэтому я сделаю то же самое.

Ответ №1:

Вам нужно вызвать обработчик завершения с результатом, чтобы отменить действие салфетки. Вот справка по 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));