Ios Tableview仅在我离开视图并返回后更新
我正在向一个项目添加注释,一切似乎都正常工作,但是我显示注释的tableview在我离开屏幕并再次返回之前不会得到正确更新 基本上,一旦输入评论并按下“发送”键,评论连同评论作者一起发布到Firebase。然后,保存这两个值的字典被循环,注释进入一个数组,而注释作者进入另一个数组(这样我就可以用数组的indexpath填充我的表视图): 这就是我的Firebase数据库的外观: 我不确定是什么问题。我感觉我在正确的位置调用了self.tableView.reloadData()。这是我的获取功能(在显示图像的Ios Tableview仅在我离开视图并返回后更新,ios,swift,uitableview,firebase,firebase-realtime-database,Ios,Swift,Uitableview,Firebase,Firebase Realtime Database,我正在向一个项目添加注释,一切似乎都正常工作,但是我显示注释的tableview在我离开屏幕并再次返回之前不会得到正确更新 基本上,一旦输入评论并按下“发送”键,评论连同评论作者一起发布到Firebase。然后,保存这两个值的字典被循环,注释进入一个数组,而注释作者进入另一个数组(这样我就可以用数组的indexpath填充我的表视图): 这就是我的Firebase数据库的外观: 我不确定是什么问题。我感觉我在正确的位置调用了self.tableView.reloadData()。这是我的获取功
FeedViewController
中,而不是带有注释的PhotoDetailController
中,通过点击FeedViewController
中的一个图像来达到PhotoDetailController
):
问题是在发布注释后重新加载tableView,还是在fetch函数中?正如我所说,firebase的一切似乎都正常工作,我只希望保存要更新的评论的tableView在发布后立即显示评论
编辑:谢谢你的建议,珍。。我尝试了您的建议,并做了一些小改动,以消除警告/错误:
@IBAction func addCommentButtonPressed(_ sender: Any) {
if !addCommentTextField.text!.isEmpty {
addComment(comment: addCommentTextField.text!)
observePostComments()
}
}
func addComment(comment: String) {
let postsCommentsRef = FIRDatabase.database().reference().child("postComments").child(self.postID)
var commentData: [String: String] = [:]
commentData["userId"] = FIRAuth.auth()!.currentUser!.displayName!
commentData["comment"] = comment
postsCommentsRef.childByAutoId().setValue(commentData)
}
func observePostComments() {
let postsCommentsRef = FIRDatabase.database().reference().child("postComments").child(self.postID)
postsCommentsRef.observe(.childAdded, with: { snapshot in
let comment = snapshot.value as! [String: String]
self.selectedPost.commentAuthors.append(comment["userId"]!)
self.selectedPost.commentText.append(comment["comment"]!)
self.tableView.reloadData()
})
}
以下是我的tableView方法:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CommentCell
cell.commentAuthorLabel?.text = selectedPost.commentAuthors[indexPath.row]
cell.commentLabel?.text = selectedPost.commentText[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return selectedPost.commentAuthors.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 72
}
它看起来像是
fetchPosts
既更新数据库又侦听更改。我建议您设置一个只更新数据库的函数。然后有一个单独的函数,该函数在视图中调用一次,并使用.observe(.childAdded)
在数据库中出现新注释时向tableView追加新注释
编辑:
由于您是Firebase新手,以下是一些简化代码和更新tableView的具体建议:
在“posts”之外创建一个单独的子级来保存评论。有时,您可能希望访问不包含评论的文章中的某些信息,因此最好保持数据库平坦,以尽量减少下载的额外数据量。使用相同的posted链接帖子和帖子评论
结果如下所示:
"posts":
"-postIdKey":
"photoPath": "..."
"name": "..."
"date": "..."
"...": "..."
"postComments:"
"-postIdKey":
"-commentIdPush1":
"userId": "uId1"
"comment": "Love this pic!"
"-commentIdPush2":
"userId": "uId2"
"comment": "Wow!"
addCommentButtonPressed
中,如果文本字段中有文本,则调用addComment,将文本作为参数传递。创建一个字典来保存要传递给setValue的数据。设置键“userId”和“comment”的值后,使用childByAutoId并传递注释数据为postCommentsRef创建一个新的子级
@IBAction func addCommentButtonPressed(_ sender: Any) {
if !addCommentTextField.text!.isEmpty {
addComment(addCommentTextField.text!)
}
}
func addComment(comment: String) {
var commentData: [String: String] = [:]
commentData["userId"] = self.userID
commentData["comment"] = comment
postCommentsRef.childByAutoId().setValue(commentData)
}
.value
事件,而是通过创建一个监听器来观察新注释,从而利用Firebase数据库是实时的这一事实。您可以在这个函数的基础上创建另一个函数来监听新帖子
let postsCommentsRef = FIRDatabase.database().reference().child("postComments").child(postID)
func observePostComments() {
postsCommentsRef.observe(.childAdded, with: { snapshot in
let comment = snapshot.value as! [String: String]
self.comments.append(comment["userId"])
self.commentAuthors.append(comment["comment"])
self.yourTableView.insertRows(at: [IndexPath(row: self.comments.count-1, section: 0)], with: .automatic)
})
}
注意#2和#3中关注点的分离
addCommentButtonPressed
只与向数据库添加新注释有关observePostComments
只关心从数据库向UITableView
添加新注释。在主线程上重新加载表。与UI相关的任务在主线程上完成。我尝试将reloadData
调用包装在DispatchQueue.main.async
中,但没有帮助。看起来评论也被加载了两次。谢谢你,这非常有用。在我意识到第2步和第3步做到这一点之前,我自己花了一些时间尝试执行第1步,最后删除/覆盖了我所有的Firebase节点,真是有趣。但不管怎样,我还是执行你的建议(在if语句中,名为addCommentButtonPressed
中的observePostCommentsRef
,并将addComment
中的postsCommentsRef
更改为postsCommentsRef
,希望这也是对的……但是我在tableview中遇到了一个崩溃。忽略上一条消息,我更改了一些。)事情进展顺利(我使用了tableView.reloadData
而不是insertRows
)现在没有崩溃。我还添加了一个viewDidAppear
,我正在那里调用observePostComments
,一切似乎都很好!再次感谢这真的很有帮助-当你学习如何使用Firebase时,Firebase非常酷,所以我需要更多的练习,但这是一个很好的参考!
@IBAction func addCommentButtonPressed(_ sender: Any) {
if !addCommentTextField.text!.isEmpty {
addComment(addCommentTextField.text!)
}
}
func addComment(comment: String) {
var commentData: [String: String] = [:]
commentData["userId"] = self.userID
commentData["comment"] = comment
postCommentsRef.childByAutoId().setValue(commentData)
}
let postsCommentsRef = FIRDatabase.database().reference().child("postComments").child(postID)
func observePostComments() {
postsCommentsRef.observe(.childAdded, with: { snapshot in
let comment = snapshot.value as! [String: String]
self.comments.append(comment["userId"])
self.commentAuthors.append(comment["comment"])
self.yourTableView.insertRows(at: [IndexPath(row: self.comments.count-1, section: 0)], with: .automatic)
})
}