如果我使用的是 SnapshotListener,如何在我的 TableView 中为行和节的删除设置动画?

How can I animate the deletion of Rows and Sections in my TableView if I'm using a SnapshotListener?

如果我使用每次数据为 added/removed 时都会调用的 SnapshotListener,我如何为删除行和部分设置动画。现在,当我滑动删除时,没有动画,rows/sections 突然消失,这是有道理的,因为我没有实现动画,也没有手动删除 rows/section。这是我的加载数据...

feedback = self.rootWorkoutsCollection.addSnapshotListener({ (snapshot, err) in
            let group = DispatchGroup()
            group.enter()

            self.workoutsCollection.daysCollection.removeAll()

            if let err = err
            {
                print("Error getting documents: \(err.localizedDescription)")
            }
            else {
                guard let workoutDocuments = snapshot?.documents else { return }

                for document in workoutDocuments {
                    var foundIt = false

                    let workoutData = document.data()
                    let day = workoutData["Day"] as! String
                    let workout = workoutData["Workout"] as! String

                    if self.workoutsCollection.daysCollection.isEmpty {

                        let newWorkout = Workout(Day: day, Workout: workout, Ref: document.reference)
                        let newDay = Day(Day: day, Workout: newWorkout, Ref: newWorkout.key)
                        self.workoutsCollection.daysCollection.append(newDay)
                        continue
                    }

                    if !foundIt{
                        for dayObject in self.workoutsCollection.daysCollection{
                            for dow in dayObject.workout{
                                if dow.day == day{
                                    let newWorkout = Workout(Day: day, Workout: workout, Ref: document.reference)
                                    dayObject.workout.append(newWorkout)
                                    foundIt = true
                                    break
                                }
                            }
                        }
                    }

                    if foundIt == false{
                        let newWorkout = Workout(Day: day, Workout: workout, Ref: document.reference)
                        let newDay = Day(Day: day, Workout: newWorkout, Ref: newWorkout.key)
                        self.workoutsCollection.daysCollection.append(newDay)
                    }

                }

            }
            group.leave()
            group.notify(queue: .main){
                self.tableView.reloadData()
            }
            }
        )

这是我用来从后端和本地删除数据的函数...

func removeWorkout(Dow: Day, Workout: Workout ){

        let db : Firestore!
        db = Firestore.firestore()
        db.collection("Users").document("\(Auth.auth().currentUser!.uid)").collection("Workouts").document(Dow.key.documentID).delete()

        if let dayIndex = daysCollection.firstIndex(of: Dow), let workoutIndex = daysCollection[dayIndex].workout.firstIndex(of: Workout) {
            daysCollection[dayIndex].workout.remove(at: workoutIndex)
        }

    }

诀窍是不要循环 snapshot?.documents,而是使用 snapshot.documentChangesdocumentChanges 集合包含有关每个文档在上一个查询快照和这个查询快照之间如何更改的信息。

来自 viewing changes between snapshots 上的 Firebase 文档:

db.collection("cities").whereField("state", isEqualTo: "CA")
    .addSnapshotListener { querySnapshot, error in
        guard let snapshot = querySnapshot else {
            print("Error fetching snapshots: \(error!)")
            return
        }
        snapshot.documentChanges.forEach { diff in
            if (diff.type == .added) {
                print("New city: \(diff.document.data())")
            }
            if (diff.type == .modified) {
                print("Modified city: \(diff.document.data())")
            }
            if (diff.type == .removed) {
                print("Removed city: \(diff.document.data())")
            }
        }
    }

然后您可以使用此额外信息通过使用上面的文档调用 reloadRowsinsertRowsdeleteRows 来为 table 视图设置动画。