Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Tableview仅在我离开视图并返回后更新_Ios_Swift_Uitableview_Firebase_Firebase Realtime Database - Fatal编程技术网

Ios Tableview仅在我离开视图并返回后更新

Ios Tableview仅在我离开视图并返回后更新,ios,swift,uitableview,firebase,firebase-realtime-database,Ios,Swift,Uitableview,Firebase,Firebase Realtime Database,我正在向一个项目添加注释,一切似乎都正常工作,但是我显示注释的tableview在我离开屏幕并再次返回之前不会得到正确更新 基本上,一旦输入评论并按下“发送”键,评论连同评论作者一起发布到Firebase。然后,保存这两个值的字典被循环,注释进入一个数组,而注释作者进入另一个数组(这样我就可以用数组的indexpath填充我的表视图): 这就是我的Firebase数据库的外观: 我不确定是什么问题。我感觉我在正确的位置调用了self.tableView.reloadData()。这是我的获取功

我正在向一个项目添加注释,一切似乎都正常工作,但是我显示注释的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)
    
        })
    }