TableViewCells错误地加载基于Firebase数据的正确图像

时间:2017-11-02 00:44:50

标签: ios swift uitableview firebase

构建新闻Feed,用户可以选择喜欢或不喜欢帖子。当该事件发生时,相似图像的颜色相应地改变。代码是正确的,并且所有后端数据都正常工作(IE:喜欢/不喜欢正确更新的值)。问题在于,当我喜欢或不喜欢帖子时,所有其他喜欢/不喜欢的图像会改变颜色并错误地显示相应的图像。以下是 tableviewcell cellforrowat 中的代码:

TableViewCell

func configureCell(post: Post) {
    self.post = post

    likesRef = FriendSystem.system.CURRENT_USER_LIKES_REF.child(self.post.postID)
    dislikeRef = FriendSystem.system.CURRENT_USER_DISLIKES_REF.child(self.post.postID)

    FriendSystem.system.CURRENT_USER_LIKES_REF.child(post.postID).observeSingleEvent(of: DataEventType.value, with: { (snapshot) in
        if let _ = snapshot.value as? NSNull{
            self.likesImage.image = #imageLiteral(resourceName: "gray_fire")
        } else {
            self.likesImage.image = #imageLiteral(resourceName: "trending_fire")
        }
    })

    FriendSystem.system.CURRENT_USER_DISLIKES_REF.child(post.postID).observeSingleEvent(of: DataEventType.value, with: { (snapshot) in
        if let _ = snapshot.value as? NSNull {
            self.dislikeImage.image = #imageLiteral(resourceName: "upsidedownGrayFire")
        } else {
            self.dislikeImage.image = #imageLiteral(resourceName: "blueFire")
        }
    })
}

喜欢

func likeTapped(sender: UITapGestureRecognizer) {

    FriendSystem.system.loadUserFriends(post.userID)
    if FriendSystem.system.USER_REF.child(post.userID).key == FriendSystem.system.CURRENT_USER_ID {
        return
    } else {
        likesRef.observeSingleEvent(of: .value, with: { (snapshot) in
            if let _ = snapshot.value as? NSNull {
                self.dislikeRef.observeSingleEvent(of: .value, with: {(snapshot) in
                    if let _ = snapshot.value as? NSNull {
                        self.likesImage.image = UIImage(named: "trending_fire")
                        self.dislikeImage.image = UIImage(named: "upsidedownGrayFire")
                        self.currentUser.adjustScore(addScore: true)
                        FriendSystem.system.postUsersFriends.forEach({ (key) in
                            self.post.adjustUserLikes(key: key, addLike: true)
                        })
                        self.likesRef.setValue(true)

                    } else {
                        self.likesImage.image = UIImage(named: "gray_fire")
                        self.dislikeImage.image = UIImage(named: "upsidedownGrayFire")
                        self.currentUser.adjustScore(addScore: true)
                        FriendSystem.system.postUsersFriends.forEach({ (key) in
                            self.post.adjustUserLikes(key: key, addLike: true)

                        })
                        self.dislikeRef.removeValue()

                    }

                })

            } else {
                self.likesImage.image = UIImage(named: "gray_fire") // Change the image
                self.dislikeImage.image = UIImage(named: "upsidedownGrayFire")
                self.currentUser.adjustScore(addScore: false)
                FriendSystem.system.postUsersFriends.forEach({ (key) in
                    self.post.adjustUserLikes(key: key, addLike: false) // Remove the like

                })
                self.likesRef.removeValue() // removes the value to false in the DB

            }
        })
    }
}

CellForRowAt

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let post = FriendSystem.system.friendPosts[indexPath.row]
    if let cell = tableView.dequeueReusableCell(withIdentifier: "postCell") as? FriendPostCell {

        cell.configureCell(post: post)
        cell.transform = CGAffineTransform(scaleX: 1, y: -1)
        cell.delegate = self
        return cell
    }
    return UITableViewCell()
}

我已经坚持了大约一个星期,我正在考虑放弃这个概念。任何帮助,将不胜感激。此外,如果有一个额外或缺少闭包,这是因为我编辑了真实的代码来显示问题。

1 个答案:

答案 0 :(得分:1)

我对“喜欢”和Firebase有类似的问题。当您使用tapGestureRecognizer时,我无法说出您的具体问题,我不确定应用的位置。但是,我可以向您展示我是如何解决我的问题的,也许我们可以分享一些代码来帮助解决这个问题。

如果我不得不猜测我会用这种方法说出你的问题:

func configureCell(post: Post) {
    self.post = post

    likesRef = FriendSystem.system.CURRENT_USER_LIKES_REF.child(self.post.postID)
    dislikeRef = FriendSystem.system.CURRENT_USER_DISLIKES_REF.child(self.post.postID)

    FriendSystem.system.CURRENT_USER_LIKES_REF.child(post.postID).observeSingleEvent(of: DataEventType.value, with: { (snapshot) in
        if let _ = snapshot.value as? NSNull{
            self.likesImage.image = #imageLiteral(resourceName: "gray_fire")
        } else {
            self.likesImage.image = #imageLiteral(resourceName: "trending_fire")
        }
    })

    FriendSystem.system.CURRENT_USER_DISLIKES_REF.child(post.postID).observeSingleEvent(of: DataEventType.value, with: { (snapshot) in
        if let _ = snapshot.value as? NSNull {
            self.dislikeImage.image = #imageLiteral(resourceName: "upsidedownGrayFire")
        } else {
            self.dislikeImage.image = #imageLiteral(resourceName: "blueFire")
        }
    })

我怀疑这是问题的原因是由于Firebase的异步性质。查询需要时间,当结果返回并应用于该单元格时,如果用户滚动,则可能会重复使用该查询。这意味着错误的细胞图像会发生变化。

首先,我建议每个帖子都有一个“userLiked”值,用于确定要显示的图像。在我的情况下,我正在更改显示哪个按钮。

在cellForRow中,您可以检查以下内容:

if dataSource[indexPath.row]!.userLiked == nil {
      DatabaseFunctions.userLiked(postID: key, cell: cell)
}

userLiked检查该用户以前是否喜欢该帖子,更新本地存储的值post.userLiked并更新单元格图像。

以下是我实现这一目标的方法:

static func userLiked(postID: String, cell: BetterPostCell) {
        let likeRef = Database.database().reference()
        if let uid = Auth.auth().currentUser?.uid {
            likeRef.child("userActivity").child(uid).child("likes").child(postID).queryOrderedByKey().observeSingleEvent(of: .value, with: { snap in
                if snap.exists() {
                    cell.helpfulButton.isHidden = true
                    cell.notHelpfulButton.isHidden = false
                    postDict[postID]?.userLiked = true

                }
                else {
                    postDict[postID]?.userLiked = false
                }
            })
        }
    }

如果您有疑问,请告诉我。