Удаление последней записи в tableview приводит к сбою приложения с недопустимым обновлением: недопустимое количество строк в разделе 0 - PullRequest
0 голосов
/ 21 июня 2020

Первый пост ...

Запуск небольшого приложения с табличным представлением Aircraft, которое, когда я смахиваю, чтобы удалить последнюю запись, приложение вылетает из-за несоответствия количества строк. Запись также не удаляется из Realm. Я пытаюсь использовать trailingSwipeActionsConfigurationForRowAt, поскольку это «более новый» способ делать что-то и можно добавить более одного действия (у меня также есть действие Edit).

Если я закомментирую self.tableView.deleteRows(at: [indexPath], with: .fade), все работает . Я просто пытаюсь вставить эту команду deleteRows, чтобы анимация выглядела лучше. При удалении только Realm он просто отделяет строку (не плавно). ИЛИ есть лучший способ сделать анимацию красивее? Код ниже ...

override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        UISwipeActionsConfiguration(actions:
                                    [makeDeleteContextualAction(forRowAt: indexPath),
                                     makeEditContextualAction(forRowAt: indexPath)])
    }
    

func makeEditContextualAction(forRowAt indexPath: IndexPath) -> UIContextualAction {
    let action = UIContextualAction(style: .normal,
                                    title: "Edit",
                                    handler: { (contextualAction: UIContextualAction, swipeButton: UIView, completionHandler: (Bool) -> Void) in
                                        print("Hit the EDIT...")
                                            })
    action.backgroundColor = .systemYellow
    return action
}

func makeDeleteContextualAction(forRowAt indexPath: IndexPath) -> UIContextualAction {
    let action = UIContextualAction(style: .destructive,
                       title: nil)
                      { (contextualAction: UIContextualAction, swipeButton: UIView, completionHandler: (Bool) -> Void) in
                        if let aircraftToDelete = self.aircraftResults?[indexPath.row] {
                            do {
                                try self.aircraftRealm.write {
                                    self.aircraftRealm.delete(aircraftToDelete)
                                    //self.tableView.deleteRows(at: [indexPath], with: .fade)   // Only to make delete look smooth
                                }
                            } catch {
                                print("Error deleting data... \(error)")
                            }
                        }
                        
                        self.loadAircraft()
                        completionHandler(true)}
    
    action.image = UIImage(systemName: "trash")
    action.backgroundColor = .systemRed
    return action
}

Затем он берет данные из Realm и перезагружает таблицу ...

func loadAircraft() {
        aircraftResults = aircraftRealm.objects(Aircraft.self)
        tableView.reloadData()
    }

Спасибо за помощь ... Скотт

Ответы [ 2 ]

0 голосов
/ 21 июня 2020

Не извлекать данные из базы данных. Вместо этого удалите элемент из массива источника данных.

Прежде всего объявите массив источника данных необязательным, чтобы избавиться от бессмысленного if let

var aircraftResults = [Aircraft]()

Затем сначала удалить элемент из базы данных. В случае успеха удалите элемент из массива источника данных и удалите строку.

И вызовите обработчик завершения, передав false при ошибке

func makeDeleteContextualAction(forRowAt indexPath: IndexPath) -> UIContextualAction {
    let action = UIContextualAction(style: .destructive,
                       title: nil)
                      { (contextualAction: UIContextualAction, swipeButton: UIView, completionHandler: (Bool) -> Void) in
                        let aircraftToDelete = self.aircraftResults[indexPath.row] {
                        do {
                            try self.aircraftRealm.write {
                                self.aircraftRealm.delete(aircraftToDelete)
                                self.aircraftResults.remove(at: indexPath.row)
                                self.tableView.deleteRows(at: [indexPath], with: .fade)   // Only to make delete look smooth
                                completionHandler(true)
                            }
                        } catch {
                            print("Error deleting data... \(error)")
                            completionHandler(false)
                        }
                       
    }
    
    action.image = UIImage(systemName: "trash")
    action.backgroundColor = .systemRed
    return action
}
0 голосов
/ 21 июня 2020

вы захотите удалить самолет из Realm, а затем deleteRows (at :, с :) между startUpdating () и stopUpdating (). Это не поможет, если Realm не удаляет ваш aircraftToDelete.

func makeDeleteContextualAction(forRowAt indexPath: IndexPath) -> UIContextualAction {
    let action = UIContextualAction(style: .destructive,
                       title: nil)
                      { (contextualAction: UIContextualAction, swipeButton: UIView, completionHandler: (Bool) -> Void) in
                        if let aircraftToDelete = self.aircraftResults?[indexPath.row] {
                            do {
                                try self.aircraftRealm.write {
                                    self.tableView.beginUpdates()                                    
                                    self.aircraftRealm.delete(aircraftToDelete)
                                    //self.tableView.deleteRows(at: [indexPath]
                                    self.tableView.endUpdates(), 
                                    with: .fade)   // Only to make delete look smooth
                                }
                            } catch {
                                print("Error deleting data... \(error)")
                            }
                        }
                        
                        self.loadAircraft()
                        completionHandler(true)}
    
    action.image = UIImage(systemName: "trash")
    action.backgroundColor = .systemRed
    return action
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...