首页 > 解决方案 > 删除 tableview 中的最后一个条目使应用程序崩溃,更新无效:第 0 节中的行数无效

问题描述

第一次发帖...

使用 Aircraft 的 tableview 启动小型应用程序,当我滑动删除最后一个条目时,应用程序崩溃,因为行数不匹配。该条目也不会从 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()
    }

感谢您的帮助...斯科特

标签: iosswift

解决方案


不要从数据库中重新获取数据。而是从数据源数组中删除该项目。

首先声明数据源数组 non-optional 摆脱无意义的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
}

推荐阅读