2

我有一个 Firebase 快照侦听器,它检查新文档,将它们添加到数组(collectionView 数据源),然后重新加载 collectionView。但是,我在 collectionView 中得到了重复的单元格。我的 Firestore 集合中目前有 3 个对象,但它们总共被复制了 9 个单元格。

我什至添加了对索引的检查,因此 reloadData 仅在到达数组末尾后发生。以下是相关代码:

messageListener = query.addSnapshotListener { querySnapshot, error in
    guard let snapshot = querySnapshot else {
        print("Error listening for channel updates: \(error?.localizedDescription ?? "No error")")
        return
    }
    
    snapshot.documentChanges.forEach { change in

        if change.type == .added {
            for document in snapshot.documents{
                
                 ....

                let newMessage = Message(sender: newSender, messageId: document.documentID, sentDate: date, text: text)
                
                self.messages.append(newMessage)
                
                guard let index = snapshot.documents.index(of: document) else {return}
                
                if index == (snapshot.documents.count - 1) {
                    self.messagesCollectionView.reloadData()
                }
            }
        }
    }
}

它正确地对索引进行倒计时,因此最终达到 2 == 2 以重新加载数据。但是,它会再次启动该过程另外两次,总共 3 次(3 个对象加载了 3 次,总共 9 个单元格)。知道如何改进此逻辑流程以停止重复吗?

谢谢!!

编辑 1

extension ChatViewController: MessagesDataSource {
    
    func currentSender() -> Sender {
        //guard let currentUserID = User.current?.key else {return nil}
        let newSender = Sender(id: (User.current?.key)!, displayName: (User.current?.username)!)
        return newSender
    }
    
        func numberOfSections(in messagesCollectionView: MessagesCollectionView) -> Int {
    return 1
}

func numberOfItems(inSection section: Int, in messagesCollectionView: MessagesCollectionView) -> Int {
    return messages.count
}
    func messageForItem(at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageType {
        return messages[indexPath.section]
        
        func cellTopLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? {
           
            return NSAttributedString(string: MessageKitDateFormatter.shared.string(from: message.sentDate), attributes: [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 10), NSAttributedString.Key.foregroundColor: UIColor.darkGray])
        }
        
        func messageTopLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? {
            let name = message.sender.displayName
            return NSAttributedString(string: name, attributes: [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .caption1)])
        }
        
        func messageBottomLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? {
            
            let dateString = formatter.string(from: message.sentDate)
            return NSAttributedString(string: dateString, attributes: [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .caption2)])
        }
    }
}
4

2 回答 2

6

messages在重新填充快照文档之前,必须重置数组。您可以self.messages.removeAll()在行前添加for document in snapshot.documents

于 2019-02-18T04:23:27.900 回答
0

您必须在之后清除包含您的对象的数组

collectionView?.refreshControl?.beginRefreshing()
self.messages = []

然后打电话

self.collectionView?.reloadData()

否则,您将收到“索引超出范围”错误

于 2019-06-19T14:40:30.867 回答