【发布时间】:2016-11-08 03:43:53
【问题描述】:
大家下午好,
我遇到了一个令人沮丧的错误,与我一直关注的聊天应用程序教程有关,并且想要补救(由于我已转换为 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)
}
我遇到的问题是关于 collectionView 滚动到的无效 indexPath。使用打印语句,我发现 reloadData() 被调用了很多,这只是我从调试控制台的假设,即 indexPath 不能“更新”或“跟上”这些值。
我对 GCD 很陌生(我只被告知应该始终在主线程上完成 UI 的更新),并且想知道我的问题的答案是否在于设置正确的同步/异步执行,或者串行/并发队列。
Ex// 使用后台线程获取会话消息并更新 indexPath,而主线程异步地重新加载数据和 scrollsToItem。
我不确定,但如果有人能对此有所了解,或指出正确的方向,我将不胜感激。非常感谢。
【问题讨论】:
标签: swift swift3 grand-central-dispatch reloaddata collectionview