You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何从Firestore获取数据的TableView无法更新单元格?

问题分析与解决方案

核心问题

  1. 数据源不同步:TableView的数据源是searchReservations,但loadReservations仅更新Reservations数组,刷新操作未将新数据同步到searchReservations,导致UI仍显示旧内容。
  2. 异步操作顺序错误:refresh方法中调用loadReservations后立刻执行reloadData和endRefreshing,但Firestore的getDocuments是异步请求,此时数据还未加载完成,刷新操作无效。
  3. 频繁刷新效率低下:loadReservations循环内每次添加数据都调用reloadData,既浪费资源又可能导致UI闪烁。

修复步骤与代码修改

1. 修正refresh方法逻辑

移除异步块内的提前刷新操作,仅触发数据加载,后续刷新逻辑交给Firestore回调处理:

@objc func refresh(send: UIRefreshControl) {
    // 清空数组避免数据重复
    self.Reservations.removeAll()
    self.loadReservations()
}

2. 同步数据源并统一刷新时机

在Firestore数据加载完成后,同步searchReservations并统一刷新TableView,同时结束刷新控件:

func loadReservations() {
    Reservations = []
    guard let uid = Auth.auth().currentUser?.uid else { return }
    let userCollection = Firestore.firestore().collection("Users")
    let thisUserDoc = userCollection.document(uid)
    
    thisUserDoc.collection("Reservations").getDocuments { (querySnapshot, error) in
        if let e = error {
            print(e)
            // 加载失败也要结束刷新
            DispatchQueue.main.async {
                self.refreshControl.endRefreshing()
            }
            return
        }
        
        guard let snapshotDocuments = querySnapshot?.documents else {
            DispatchQueue.main.async {
                self.refreshControl.endRefreshing()
            }
            return
        }
        
        for doc in snapshotDocuments {
            let data = doc.data()
            if let Time = data["Time"] as? String, 
               let Date = data["Date"] as? String, 
               let Guests = data["Guests"] as? String, 
               let RestaurantName = data["RestaurantName"] as? String, 
               let Name = data["Name"] as? String, 
               let Status = data["Status"] as? String, 
               let Phone = data["Phone"] as? String, 
               let Id = data["Id"] as? String, 
               let RestaurantId = data["RestaurantID"] as? String, 
               let Id2 = data["Id2"] as? String, 
               let guestId = data["GuestId"] as? String {
                
                let newReservation = Reservation(id: Id, userId: guestId, id2: Id2,restaurantId: RestaurantId ,restaurantName: RestaurantName, name: Name, phone: Phone, guests: Guests, time: Time, date: Date, status: Status)
                self.Reservations.append(newReservation)
            }
        }
        
        // 所有数据加载完成后同步数据源并刷新UI
        DispatchQueue.main.async {
            self.searchReservations = self.Reservations
            self.reservationsTableView.reloadData()
            self.refreshControl.endRefreshing()
        }
    }
}

3. 移除循环内的局部刷新

删除loadReservations循环中的DispatchQueue.main.async { self.reservationsTableView.reloadData() },改为统一刷新。


额外优化建议

  • 遵循Swift命名规范:变量名首字母小写(如Reservations改为reservations),提升代码可读性。
  • 若searchReservations用于搜索过滤,可在loadReservations完成后调用过滤逻辑再赋值,确保搜索状态下刷新也能正确显示结果。

内容的提问来源于stack exchange,提问作者Branislav Fekeč

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 19:20:53