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

时间:2017-03-17 17:52:54

标签: ios swift uitableview firebase firebase-realtime-database

我正在为项目添加评论,一切似乎都在运行,但是我的桌面视图显示评论并没有得到正确更新,直到我离开屏幕然后再返回。

一旦输入评论并且"发送"按下,评论以及评论作者将发布到Firebase。然后将包含这两个值的字典循环并将注释放入一个数组中,同时注释作者进入另一个数组(这样我就可以使用数组' indexPaths填充我的表视图):

@IBAction func addCommentButtonPressed(_ sender: Any) {

    if addCommentTextField.text != nil {
        if let comment = addCommentTextField.text {
            print(comment)

            let ref = FIRDatabase.database().reference()
            let keyToPost = ref.child("posts").childByAutoId().key

            ref.child("posts").child(self.postID).observeSingleEvent(of: .value, with: { (snapshot) in

                if let post = snapshot.value as? [String : AnyObject] {

                    let updateComments: [String: Any] = ["comments/\(FIRAuth.auth()!.currentUser!.displayName!)" : comment]
                    ref.child("posts").child(self.postID).updateChildValues(updateComments, withCompletionBlock: { (error, reff) in

                        if error == nil {
                            ref.child("posts").child(self.postID).observeSingleEvent(of: .value, with: { (snap) in

                                if let properties = snap.value as? [String: AnyObject] {

                                    if let commentLoop = post["comments"] as? [String : AnyObject] {
                                        for (person, comment) in commentLoop {
                                            self.selectedPost.commentAuthors.append(person)
                                            self.selectedPost.commentText.append(comment as! String)
                                        }
                                    }

                                    DispatchQueue.main.async {
                                        self.tableView.reloadData()
                                    }
                                }
                            })
                        }
                    })
                }
            })
            ref.removeAllObservers()
        }
    }
    addCommentTextField.resignFirstResponder()
    self.addCommentTextField.text = nil
    self.view.endEditing(true)
    self.addCommentView.isHidden = true
}

这就是我的Firebase数据库的样子:

enter image description here

我不确定问题是什么。我觉得我在正确的地方打电话给self.tableView.reloadData()。这是我的获取功能(在显示图片的FeedViewController中,而不是通过点击{{1}中的一个图片来获得评论PhotoDetailController的{​​{1}} }}):

PhotoDetailController

在发布评论后重新加载tableView会出现问题,还是在fetch函数中?就像我说的一切似乎都与firebase一起正常工作一样,我就像tableView一样,它会更新评论,以便在发布后立即显示评论。

编辑:感谢Jen的精彩建议..我尝试了一些小改动,以摆脱警告/错误:

FeedViewController

这些是我的tableView方法:

func fetchPosts() {

    let ref = FIRDatabase.database().reference()
    ref.child("users").queryOrderedByKey().observe(.value, with: { snapshot in

        let users = snapshot.value as! [String : AnyObject]

        for (_, value) in users {
            // get uid as string
            if let uid = value["uid"] as? String {
                // check to make sure uids match
                if uid == FIRAuth.auth()?.currentUser?.uid {
                    // check for followers
                    if let followingUsers = value["following"] as? [String : String] {
                        // loop through those and add them to "following" array
                        for (_, user) in followingUsers {
                            self.following.append(user)
                        }
                    }
                    // add current user to that array also so you can see your own posts
                    self.following.append(FIRAuth.auth()!.currentUser!.uid)

                    ref.child("posts").queryOrderedByKey().observeSingleEvent(of: .value, with: { (snap) in
                        let postsSnap = snap.value as! [String : AnyObject]

                        for (_, post) in postsSnap {
                            if let userID = post["userID"] as? String {
                                for each in self.following {
                                    if each == userID {
                                        // here are the posts that the user should see (his own and his following)
                                        let posst = Post()
                                        if let author = post["author"] as? String, let likes = post["likes"] as? Int, let pathToImage = post["pathToImage"] as? String, let postID = post["postID"] as? String {

                                            posst.author = author
                                            posst.likes = likes
                                            posst.pathToImage = pathToImage
                                            posst.postID = postID
                                            posst.userID = userID
                                            if let people = post["peopleWhoLike"] as? [String : AnyObject] {
                                                for (_, person) in people {
                                                    posst.peopleWhoLike.append(person as! String)
                                                }
                                            }

                                            if let commentLoop = post["comments"] as? [String : AnyObject] {
                                                for (person, comment) in commentLoop {
                                                    posst.commentAuthors.append(person)
                                                    posst.commentText.append(comment as! String)
                                                }
                                            }

                                            posts.append(posst)
                                        }
                                    }
                                }
                                self.collectionView.reloadData()
                            }
                        }
                    })
                    ref.removeAllObservers()
                }
            }
        }
    })
}

1 个答案:

答案 0 :(得分:3)

看起来fetchPosts都会更新数据库并侦听更改。我建议您设置仅更新数据库的功能。然后有一个单独的函数在视图中调用一次,并使用.observe(.childAdded)在tableView出现在数据库中时将新注释附加到tableView。

编辑: 由于您不熟悉Firebase,因此以下是一些简化代码和更新tableView的具体建议:

在"帖子"之外创建一个单独的孩子。举行评论。有时您可能希望从不包含评论的帖子中访问某些信息,因此最好通过保持数据库保持平稳来最小化您下载的额外数据量。使用相同的postId链接帖子和帖子评论。

结果看起来像这样:

"posts":
    "-postIdKey":
        "photoPath": "..."
        "name": "..."
        "date": "..."
        "...":  "..."          

"postComments:"
     "-postIdKey":
         "-commentIdPush1":
             "userId": "uId1"
             "comment": "Love this pic!"
         "-commentIdPush2":
             "userId": "uId2"
             "comment": "Wow!"
  1. addCommentButtonPressed中,如果文本字段中有文本,请调用addComment,将文本作为参数传递。创建一个字典来保存您将传递给setValue的数据。一旦您设置了密钥的值,就可以使用#Id; userId"和"评论",使用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)
    }
    
  2. 不是观察.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)
    
        })
    }
    
  3. 注意#2和#3中关注点的分离。 addCommentButtonPressed仅关注向数据库添加新注释。 observePostComments仅关注从数据库向UITableView添加新评论。