下午好一切,的CollectionView:scrollToItem,reloadData,並調度隊列
我遇到了一個令人沮喪的錯誤關於我一直在下面聊天應用教程,想補救(本教程沒有解決這個問題,因爲我已經轉換爲Swift 3/Xcode8)。讓我試着描述這個問題:
兩個用戶之間的聊天日誌利用Firebase數據庫來存儲和檢索它們之間的會話消息。我正在使用collectionView來顯示對話。我想在聊天記錄中實現一項功能,這樣當用戶選擇要查看的對話時,它會滾動到最新/最後的「消息」,以便用戶輕鬆地繼續對話。
下面是聊天記錄器當前的相關代碼:
func observeMessages() {
guard let uid = FIRAuth.auth()?.currentUser?.uid, let toId = user?.id else {
return
}
let userMessagesRef = FIRDatabase.database().reference().child("user-messages").child(uid).child(toId)
userMessagesRef.observe(.childAdded, with: { (snapshot) in
let messageId = snapshot.key
let messagesRef = FIRDatabase.database().reference().child("messages").child(messageId)
messagesRef.observeSingleEvent(of: .value, with: { (snapshot) in
guard let dictionary = snapshot.value as? [String: AnyObject] else {
return
}
self.messages.append(Message(dictionary: dictionary))
DispatchQueue.main.async(execute: {
self.collectionView?.reloadData()
let indexPath = IndexPath(item: self.messages.count - 1, section: 0)
self.collectionView?.scrollToItem(at: indexPath, at: .bottom, animated: true)
})
}, withCancel: nil)
}, withCancel: nil)
}
我現在遇到的問題是關於無效indexPath爲的CollectionView滾動到。使用打印語句,我發現reloadData()被調用了很多,這只是我從調試控制檯的假設,indexPath不能「更新」或「跟上」這些值。
我對GCD很新穎(我只被告知UI的更新應該總是在主線程中完成),並且想知道我的問題的答案是否在於設置正確的同步/異步執行,或串行/併發隊列。例如:
Ex //使用後臺線程獲取會話消息並更新indexPath,而主線程異步地重載數據和scrollsToItem。
我不確定,但是如果有人能夠對此作出點亮,或者指引我朝着正確的方向發展,我會非常感激。非常感謝。
謝謝Nikita和Sanju。我已經做出了改變,似乎緩解了所有問題。從現在開始,我一定會保留主線程中的數據列表。 – iMoment