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

标签 ios swift uitableview firebase

构建新闻提要,用户可以选择喜欢或不喜欢帖子。发生此事件时,点赞图像的颜色会相应变化。代码是正确的,所有后端数据都在工作(即:喜欢/不喜欢的值正确更新)。问题是当我喜欢或不喜欢某个帖子时,所有其他喜欢/不喜欢的图像都会改变颜色并错误地显示相应的图像。以下是 tableviewcellcellforrowat 中的代码:

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

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

最佳答案

我对“喜欢”和 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”,用于确定要显示的图像。在我的例子中,我正在更改显示哪个喜欢的按钮。

在 cellForRowAt 你检查这样的东西:

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

如果您有任何问题,请告诉我。

关于ios - TableViewCells 错误地加载基于 Firebase 数据的正确图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47065841/

相关文章:

ios - 嵌入在容器中的 Swift TableView

ios - UITextfield 在完成按钮单击 tableview 标题时删除

ios - UISwipeGestureRecognizerDirection 仅识别正确的手势

ios - 谁在为 UITableView 调用 reloadData 方法

ios - 无法从处理程序访问类中存在的变量

ios - asyncAfter 不延迟指定时间的第一次执行

SwiftUI ScrollView 只向一个方向滚动

swift - 如何对在单独函数中创建的 UIStackView 元素进行动画处理

ios - 刷新时,UI TableView 以错误的顺序使可重用单元出队

ios - 如何测试键盘是否覆盖了 UITableView 中的 UITextField?