こんにちは、CollectionView:scrollToItem、reloadData、およびすべての派遣キュー
私は(チュートリアルでは対応していない私は、次のしてきたチャットアプリケーションのチュートリアルについてイライラするバグに遭遇していて、改善したいと思いますこの問題は私がSwift 3/Xcode8に変換して以来)。
2人のユーザ間のチャットログは、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)
}
私が遭遇してる問題はcollectionViewがにスクロールするための無効indexPathに関してです。 print文を使用すると、reloadData()が多く呼び出されていることがわかりました。これは、indexPathが値を「更新」または「保持」できないというデバッグコンソールからの私の前提です。
私はGCDの新機能を覚えています(UIへのアップデートは常にメインスレッド上で実行する必要があると言われています)、私の問題に対する答えが適切な同期/非同期実行の設定にあるのだろうか、またはシリアル/並行キュー。
例//会話メッセージをフェッチしてindexPathを更新するためにバックグラウンドスレッドを使用し、メインスレッドは非同期にreloadsDataとscrollsToItemを更新します。
私は確信していませんが、誰かがこれについて少しの光を当てたり、正しい方向に向けることができれば、本当に感謝しています。本当にありがとう。
ニキータとサンジュさんありがとうございました。私は変更を加え、すべての問題を緩和するように見える。これからはメインスレッドでデータリストを管理しておきます。 – iMoment