问题 滚动UITableView上的值更改


我有一个带有按钮的UITableView,根据用户是否“收藏”一个帖子来切换。一切都很好,除了滚动表格视图,按钮改变。这是我的代码:

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    guard let feed = self.feed else {
        return 0
    }
    return feed.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    if feed!.count > 9 {
        if indexPath.row == feed!.count - 1 {
            self.loadMorePosts()
        }
    }

    if hasImageAtIndexPath(indexPath) {
        return imageCellAtIndexPath(indexPath)

    } else {
        return basicCellAtIndexPath(indexPath)
    }

}

func hasImageAtIndexPath(indexPath:NSIndexPath) -> Bool {
    let post = self.feed?[indexPath.row]

    if post?.image?.isEmpty == false {
        return true
    }

    return false
}

func imageCellAtIndexPath(indexPath:NSIndexPath) -> PostCellImage {
    let cell:PostCellImage = self.tableView.dequeueReusableCellWithIdentifier("imageCell", forIndexPath: indexPath) as! PostCellImage


    if let post = self.feed?[indexPath.row] {
        let likedPost = post.hasFavorited

        if likedPost == true {
            if let favoriteCount = post.favoriteCount {
                let count = String(favoriteCount)
                cell.likeButton.setTitle(count, forState: .Normal)
                cell.likeButton.setImage(UIImage(named: "liked"), forState: .Normal)
                cell.likeButton.setTitleColor(UIColorFromRGB("A61224"), forState: .Normal)
                cell.likeButton.addTarget(self, action: "unfavoritePost:", forControlEvents: UIControlEvents.TouchUpInside)
                cell.likeButton.tag = post.id!
            }
        } else {
            if let favoriteCount = post.favoriteCount {
                let count = String(favoriteCount)
                cell.likeButton.setTitle(count, forState: .Normal)
                cell.likeButton.addTarget(self, action: "favoritePost:", forControlEvents: UIControlEvents.TouchUpInside)
                cell.likeButton.tag = post.id!
            }
        }
    }

    return cell
}

收藏的帖子数组

var favoritedPosts =  [Int]()

表视图

if let likedPost = post.hasFavorited {
    if likedPost == true {
        self.favoritedPosts.append(indexPath.row)             
        print(self.favoritedPosts)
    }
}

if self.favoritedPosts.contains(indexPath.row) {
    let count = String(post.favoriteCount)
    cell.likeButton.setTitle(count, forState: .Normal)
    cell.likeButton.setImage(UIImage(named: "liked"), forState: .Normal)
    cell.likeButton.setTitleColor(UIColorFromRGB("A61224"), forState: .Normal)
    cell.likeButton.addTarget(self, action: "unfavoritePost:", forControlEvents: UIControlEvents.TouchUpInside)
    cell.likeButton.tag = post.id!     
} else {
    let count = String(post.favoriteCount)
    cell.likeButton.setTitle(count, forState: .Normal)
    cell.likeButton.addTarget(self, action: "favoritePost:", forControlEvents: UIControlEvents.TouchUpInside)
    cell.likeButton.tag = post.id!        
}  

7136
2018-05-23 23:50


起源

这通常是一个小问题,我认为每个人都会有一次或几次。我假设你正在使用 dequeReusableCells 方法。当您滚动时,该方法将继续吐出已经在桌面上但出于效率原因而在窗口之外的单元格。如果您不为单元格中的每个元素提供值,则使用条件设置某些ui元素时,它将继续使用单元格的旧值,从而产生意外结果。我不是100%肯定这是你的问题我会建议包括整体 cellForRowAtIndexPath 你问题中的方法。 - Blake Lockley
刚刚添加了该代码 - Alex Smith
你应该补充一下 else 部分到你的所有嵌套 if 声明,以避免重复使用单元格导致的任何问题。请试试这个。 - Rohan Sanap
嘿@AlexSmith不确定你是否仍然没有解决这个问题。请看看我的答案 stackoverflow.com/a/37826482/6458001 下面。如果这适合您,请将其标记为正确,以便其他一些开发人员可以帮助。 - Tarun Tyagi


答案:


在你的 UITableViewCell  PostCellImage 你应该覆盖的子类 prepeareForReuse 功能 - 将单元格设置为默认模式。

迅速:

override func prepareForReuse() {
    super.prepareForReuse()

    //set cell to initial state here 
    //set like button to initial state - title, font, color, etc.
}

11
2018-06-14 22:34



这就解决了我的问题。 - Alex Smith
太棒了,我很乐意帮忙。 - Evgeny Karkan


这可能是由表视图单元重用引起的。事实证明,当帖子是收藏的帖子时,您的代码会设置likeButton.image,但是当帖子不是收藏的帖子时,您的代码不会删除图片。因此,当第一次将每个单元格加载到tableView中时,每件事都可以正常工作。但是,当滚动tableView时,当具有喜欢的图像集的那些单元格移出屏幕区域时,它们将被重新用于滚动的单元格。因此,如果这种单元格被甚至不被收藏的帖子重用,则图像仍然会在那里。

UITableViewCell有一个prepareForReuse方法,它让您有机会在重用单元格之前重置内容。


5
2018-05-24 00:14



我似乎无法找到prepareForReuse方法......其他人有这个问题吗?也许这就是为什么问题的赏金说:“目前的答案已经过时,并且需要根据最近的变化进行修改。” - Pranav Wadhwa
@penatheboss:这个方法是UITableViewCell方法的一种方法。在你的UITableViewCell子类中覆盖它。 - truongky
@truongky哦!这更有意义。谢谢! - Pranav Wadhwa


您可以尝试prepareForReuse或尝试在案例中设置不同的图像 likedPost == false


0
2018-06-15 03:10





  • 您需要在此处完全重置正常情况的外观。
  • 原因是你无法确定你获得的按钮状态 细胞被重复使用。
  • 当你收到一个出列的单元格时,它可能有一个 “喜欢”/“不喜欢”状态的按钮。
  • 用两条注释掉的线完成外观 else 条款将解决您的问题。

     if self.favoritedPosts.contains(indexPath.row) {
        let count = String(post.favoriteCount)
        cell.likeButton.setTitle(count, forState: .Normal)
        cell.likeButton.setImage(UIImage(named: "liked"), forState: .Normal)
        cell.likeButton.setTitleColor(UIColorFromRGB("A61224"), forState: .Normal)
        cell.likeButton.addTarget(self, action: "unfavoritePost:", forControlEvents: UIControlEvents.TouchUpInside)
        cell.likeButton.tag = post.id!
    } else {
        let count = String(post.favoriteCount)
        cell.likeButton.setTitle(count, forState: .Normal)
    
        // Uncomment these two lines and add proper values for image / color to resolve your problem
        // cell.likeButton.setImage(UIImage(named: "not-liked-yet"), forState: .Normal)
        // cell.likeButton.setTitleColor(UIColorFromRGB("A67832"), forState: .Normal)
    
        cell.likeButton.addTarget(self, action: "favoritePost:", forControlEvents: UIControlEvents.TouchUpInside)
        cell.likeButton.tag = post.id!        
    }
    

希望这可以帮助。


0
2018-06-15 04:58



出于某种原因,即使评论出这两行,我也遇到了同样的问题。 - Alex Smith
@AlexSmith你不应该评论那些。这些是你的问题的解决方案。请仔细阅读我的最后一点。 在else子句中使用两个注释掉的行完成外观将解决您的问题。 您需要在此处为​​图像和颜色提供正常(不可用)的案例值。 - Tarun Tyagi
@AlexSmith我刚刚重新格式化了我的答案。看看它。这应该澄清我的意思。 - Tarun Tyagi