簡體   English   中英

只有離開視圖並返回后,Tableview才會更新

[英]Tableview only updating after I leave the view and come back

我正在向項目中添加評論,並且一切似乎都可以正常工作,但是顯示評論的表格視圖直到在我離開屏幕然后再次返回之前都無法正確更新。

基本上,一旦輸入評論並按下“發送”,該評論以及評論作者便會發布到Firebase。 然后,將包含這兩個值的字典循環通過,並將注釋放入一個數組中,而將注釋作者放入另一個數組中(這是我可以用數組的indexPath填充表視圖的原因):

@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數據庫的樣子:

在此處輸入圖片說明

我不確定是什么問題。 我覺得我在正確的位置調用了self.tableView.reloadData() 這是我取功能(在FeedViewController ,其中顯示圖像,而不是PhotoDetailController它有意見- PhotoDetailController是通過點擊圖像中的一個達到FeedViewController ):

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()
                }
            }
        }
    })
}

注釋一旦發布,是重新加載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:

在“帖子”之外創建一個單獨的子項來保存評論。 有時您可能希望從帖子中訪問一些不包含評論的信息,因此最好通過保持數據庫平坦來最大程度地減少下載的額外數據量。 使用相同的postId鏈接帖子和帖子評論。

結果看起來像這樣:

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

"postComments:"
     "-postIdKey":
         "-commentIdPush1":
             "userId": "uId1"
             "comment": "Love this pic!"
         "-commentIdPush2":
             "userId": "uId2"
             "comment": "Wow!"
  1. 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) } 
  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) }) } 

注意#2和#3中關注點的分離。 addCommentButtonPressed僅與向數據庫添加新注釋有關。 observePostComments僅與將新注釋從數據庫添加到UITableView有關。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM