【问题标题】:How do I delete a cell from tableview如何从表格视图中删除单元格
【发布时间】:2021-07-14 02:06:54
【问题描述】:

我试图从 tableview 和 Firestore 中删除一个单元格。 这就是我声明我的购物车的方式:

struct Cart
{
    var photoKeyCart: String
    var foodCart: String
    var priceCart: Int
}

var cart: [Cart] = [] // This is in the cart controller

这是我的桌面视图,其中有我的购物车物品:

extension CartViewController: UITableViewDelegate, UITableViewDataSource
{
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        var sum = 0
        
        for item in cart{
            sum += item.priceCart
        }
        
        priceTotalLabel.text = "\(sum) lei"
        return cart.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = cartTableView.dequeueReusableCell(withIdentifier: "CartTableViewCell", for: indexPath) as! CartTableViewCell
        let carts = cart[indexPath.row]
        let storageRef = Storage.storage().reference()
        let photoRef = storageRef.child(carts.photoKeyCart)
        
        cell.foodInCartPrice.text = " \(carts.priceCart) lei "
        cell.foodInCartName.text = carts.foodCart
        cell.foodInCartImage.sd_setImage(with: photoRef)
        cell.foodInCartImage.layer.borderWidth = 1
        cell.foodInCartImage.layer.masksToBounds = false
        cell.foodInCartImage.layer.borderColor = UIColor.black.cgColor
        cell.foodInCartImage.layer.cornerRadius = cell.foodInCartImage.frame.height/2
        cell.foodInCartImage.clipsToBounds = true
        
        return cell
        
    }

这就是我将 Firestore 中的数据放入购物车的方式。这在确实加载的视图中调用。

func getCartProducts() {
        
        let db = Firestore.firestore()
        let userID = (Auth.auth().currentUser?.uid)!
        db.collection("CartDatabase").document(userID).collection("CartItems").getDocuments {  (document, error) in
            if let error = error {
                print(error)
                return
            } else {
                for document in document!.documents {
                    let data = document.data()
                    let newEntry = Cart(photoKeyCart: data["photoKeyCart"] as! String, foodCart: data["foodCart"] as! String , priceCart: data["priceCart"] as! Int
                    )
                    
                    
                    
                    
                    self.cart.append(newEntry)
                }
            }
            DispatchQueue.main.async {
                //  self.datas = self.filteredData
                self.cartTableView.reloadData()
            }
        }
    }

而且,这就是我尝试从 tableview 以及 Firestore 中删除单元格的方式。

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }
    
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        
        
        let carts = cart[indexPath.row]
        let storageRef = Storage.storage().reference()
        let photoRef = storageRef.child(carts.photoKeyCart)
        
        photoRef.delete { error in
            if let error = error {
                print(error.localizedDescription)
            } else {
                print("File deleted successfully")
            }
        }
        
        
        
     
        let db = Firestore.firestore()
        let userID = (Auth.auth().currentUser?.uid)!
        db.collection("CartDatabase").document(userID).collection("CartItems").getDocuments {  (document, error) in
            if let error = error {
                print(error.localizedDescription)
            } else {
                for document in document!.documents {
                    //print("\(document.documentID) => \(document.data())")
                    db.collection("CartDatabase").document(userID).collection("CartItems").document(document.documentID).delete()
                    //self.db.collection("users").document((user?.uid)!).collection("children").document("\(document.documentID)").delete()
                }
            }}
        
        
        
      
        cart.remove(at: indexPath.row)
        tableView.deleteRows(at: [indexPath], with: .fade)
        
    }
}

我有以下问题。当我试图删除单元格时,它可以工作,但是当我关闭购物车并再次返回购物车时,它会删除购物车中的所有项目,而不仅仅是我试图删除的项目。

我想要实现的目标:只删除选定的单元格。 帮助:D

更新: 我有一个包含食物的表格视图,每个单元格都是不同的食物之王。我有一个加号按钮,当点击加号按钮时,我会将食物的数据发送到 Firestore,然后在购物车中检索数据。

这就是我将数据发送到购物车的方式:

    func updateDocument(collection: String, newValueDict: [String : Any], completion:@escaping (Bool) -> Void = {_ in }) {
        
                    
                     let db = Firestore.firestore()
        let userID = (Auth.auth().currentUser?.uid)!
        db.collection(collection).document(userID).collection("CartItems").document().setData(newValueDict, merge: true){ err in
                        if let err = err {
                            print("Error writing document: \(err)")
                            completion(false)
                            
                        }else{
                            
                            completion(true)
                          
                           
                        }
                    }
                     
                 }

当我点击单元格时:

cell.didTapButton = {
            
            self.updateDocument(collection: "CartDatabase",newValueDict: ["foodCart" : mancare.foodName, "photoKeyCart": mancare.photoKeyRestaurant, "priceCart": mancare.priceFood])
           
        }

查看照片 Photo1 Photo2

【问题讨论】:

  • 在 Firebase 闭包中不需要 DispatchQueue.main.async {。 UI 调用总是在主线程上完成;网络是在后台线程上完成的。为什么要从 Firebase 获取文档然后删除它们?这浪费了很多带宽。
  • 那么,这就是@Jay 的问题?
  • 没有。查看我更新的评论。
  • 我认为存在整体设计问题;从 Firebase 读取数据时,每个文档都会有一个 documentId - 它应该是 Cart 对象以及 CartItems 的属性。当用户删除 cartItem 时,您将知道他们选择删除哪一行,然后可以从您的 dataSource 中获取该对象。然后,您将拥有 documentId,并可以将其从数组中删除(按索引),还可以通过该 documentId 从 Firebase 中删除它。
  • @Jay,感谢 Jay 的回复。我现在在家,我可以尝试其他方法来让它发挥作用。所以我需要在我的购物车结构中添加一个 documentId 并在 Firebase 中的 CartItems 中添加?之后,我需要对我的代码进行哪些更改?

标签: swift firebase uitableview google-cloud-firestore


【解决方案1】:

如果没有看到所有代码,很难提供一个具体的例子,但让我在高层次上介绍一下。

假设我们有一个帖子类对象

class PostsClass {
   var docId = ""
   var post = ""
}

和一个类数组(又名“数据源”)来存储它们

var postsArray = [PostsClass]()

第一步是从 Firebase 加载所有帖子,将 docId 和帖子文本存储在每个类中,然后将类存储在 dataSource 数组中。

myFirebase.getDocuments { doc...
   for doc in documents { //iterate over the documents and populate the array
      let post = PostClass(populate with data from firebase)
      self.postsArray.add(post)
   }
}

dataSouce 数组将如下所示

postsArray[0] = some post
postsArray[1] = another post

等等,所有这些都显示在一个tableView中。

然后用户决定删除第 1 行的帖子。因此他们滑动第一行,这会触发一个 tableView 委托事件,让应用知道滑动行的索引。

第 1 步:然后根据滑动的行索引从数组中获取该帖子

let postToDelete = self.postsArray[swiped index]
let docIdToDelete = postsToDelete.docID

第 2 步:然后将其从数组中移除

self.postsArray.deleteRow(atIndex: swiped index)

第 3 步:然后将其从 Firebase 中删除。

self.my_firebase.collection("posts").document(docIdToDelete).delete {....

注意func tableView:tableView:commit editingStyle会在该行被删除时呈现.delete的编辑风格,同时提供indexPath.row中的索引

【讨论】: