Firebase + Swift:无法删除 tableView 中的行

Posted

技术标签:

【中文标题】Firebase + Swift:无法删除 tableView 中的行【英文标题】:Firebase + Swift: Unable to delete rows in tableView 【发布时间】:2016-09-04 05:04:56 【问题描述】:

我对编码领域相当陌生,我正在尝试使用 Firebase 实现 tableView。我想要实现的是:

    使用 tableView 创建一个“设置”页面,用户可以在其中输入他们最喜欢的位置 创建一个表单(我在这里使用 Eureka),让用户从他们在设置页面中输入的收藏夹中选择某些选项 允许删除那些“收藏夹”

为了使表单正常工作,我在 AppDelegate 中提取了由 user.uid 过滤的 Firebase 数据。填充那些“收藏夹设置”。当我尝试在 'settings' 使用 commitEdittingStyle 删除行时,它会引发无效行数的错误。我尝试使用谷歌搜索各种解决方案,也尝试了 dispatch_async,但不知何故并不能完全解决我的问题。我的一些sn-ps代码如下:

public var setUpFavLocations: [(String)] = []
public var favLocDatabase: [FIRDataSnapshot]! = []


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate 

var window: UIWindow?
var ref: FIRDatabaseReference!
var _refHandle: FIRDatabaseHandle!

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool 

    FIRApp.configure()

    let favLocVC: UITableViewController = FavLocationsTableViewController(style: UITableViewStyle.Plain)


    ref = FIRDatabase.database().reference()

    if let user = FIRAuth.auth()?.currentUser 

        self.ref.child("settings").queryOrderedByChild("user").queryEqualToValue(user.uid).observeEventType(.ChildAdded, withBlock:  (snapshot) in
            favLocDatabase.append(snapshot)
            let insertionIndexPath = NSIndexPath(forRow: favLocDatabase.count - 1, inSection: 0)
            favLocVC.tableView.insertRowsAtIndexPaths([insertionIndexPath], withRowAnimation: .Automatic)
        )

        self.ref.child("settings").queryOrderedByChild("user").queryEqualToValue(user.uid).observeEventType(.ChildAdded, withBlock:  (snapshot) in
            setUpFavLocations.append(snapshot.value?["favLocation"] as! String)
        )

//At FavLocationsTableViewController, aka at the settings page
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    print("count \(setUpFavLocations.count)")
    return setUpFavLocations.count


override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) 

    if editingStyle == .Delete 

        if let user = FIRAuth.auth()?.currentUser 
            let row = favLocDatabase[indexPath.row]

            self.ref.child("settings").queryOrderedByChild("user").queryEqualToValue(user.uid).observeEventType(.ChildRemoved, withBlock:  (snapshot) -> Void in
                   favLocDatabase.removeAtIndex(indexPath.row)
                   self.tableView.deleteRowsAtIndexPaths([NSIndexPath(forRow: indexPath.row, inSection: 0)], withRowAnimation: .Automatic)

            )
            row.ref.removeValue()
        

    

这样做会引发以下错误

由于未捕获的异常而终止应用程序 'NSInternalInconsistencyException',原因:'无效更新:无效 第 0 节中的行数。包含在第 0 节中的行数 更新后的现有节(5)必须等于 更新之前该部分中包含的行 (5),加号或减号 从该部分插入或删除的行数(0 插入, 1 已删除)并加上或减去移入或移出的行数 该部分(0 移入,0 移出)。'

请帮忙,我好几天都被困在这里了。非常感谢。

【问题讨论】:

等等,你不是说你使用 Eureka 吗?为什么不在这里也使用 Eureka?这要容易得多 @Sweeper 我找不到最适合此目的的 Eureka 单元。 您是否从数据库中删除了两次该项目(removeAtIndexremoveValue)?以及为什么要创建一个新的索引路径而不是只使用参数中传递的(实际上相同的)路径? @vadian removeAtIndex 是在仅侦听 .ChildAdded 时删除从 AppDelegate 附加的 favLocDatabase 的那个。但是 removeValue 会删除 Firebase 中的数据点。 【参考方案1】:

每次删除一行时,您都在创建一个新的侦听器,这可不好。

尝试移动:

self.ref.child("settings").queryOrderedByChild("user").queryEqualToValue(user.uid).observeEventType(.ChildRemoved, withBlock:  (snapshot) -> Void in
    favLocDatabase.removeAtIndex(indexPath.row)
    self.tableView.deleteRowsAtIndexPaths([NSIndexPath(forRow: indexPath.row, inSection: 0)], withRowAnimation: .Automatic)
)

与其他侦听器一起进入您的 AppDelegate。

另外我注意到你没有处理你的观察者,所以当你打开和关闭你的应用程序时,观察者会复制。您应该在应用程序进入后台时移除观察者,并在应用程序进入前台时重新实例化它们。您将在 AppDelegate 中找到这些事件的方法。

【讨论】:

如何在 AppDelegate 中获取 indexPath?

以上是关于Firebase + Swift:无法删除 tableView 中的行的主要内容,如果未能解决你的问题,请参考以下文章

Firebase + Swift 删除 TableView 中的行

如何在 Swift 中呈现 UI 视图并保留 Tab 栏

如何从 Firebase (Swift) 中删除一个孩子

如何使用 Swift 从 UITableViewCell 中删除 Firebase 中的特定子节点

如何从特定的 UICollectionViewCell 中删除 firebase 子节点 - Swift

无法将 Firebase 导入 Swift 类