【问题标题】:Cell repopulating over each other in TableView单元格在 TableView 中相互重新填充
【发布时间】:2016-03-16 23:43:25
【问题描述】:

我目前正在使用包含三个部分的表格视图。每个部分从一个从后端加载并存储在本地数组中的数组加载它的数据。数据下载并显示没有问题,但是一旦我滚动,单元格就会重新加载它们之前的数据。在内存警告之外,我抓住它的原因是单元格包含一个带有阴影的图像,并且每次滚动阴影都会变暗。我觉得这个问题与我如何在 indexPath 为每个部分调用单元格有关,但似乎找不到解决方案。我已经四处搜索,但还没有找到解决方案。

所有单元都共享相同的自定义类并通过相同的出口重新加载各自的数据。 不确定这是否与问题相关,但视图是从 AppDelegate 中的信息调用的。 这是我正在使用的代码,它关注部分中的行数。

覆盖 func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    if section == 0 {

        return likesName.count

    } else if section == 1 {

        return commentsName.count

    } else if section == 2 {

        return bookmarksName.count

}

    return 1
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = UITableViewCell()

    if indexPath.section == 0 {

        let cell = tableView.dequeueReusableCellWithIdentifier("toggleCell", forIndexPath:indexPath) as! RightToggleCell

    cell.userAvatar.layer.cornerRadius = cell.userAvatar.frame.size.width/2
    cell.userAvatar.clipsToBounds = true

    cell.artworkImage.contentMode = UIViewContentMode.ScaleAspectFill
    cell.artworkImage.clipsToBounds = true

    cell.artistName.text = likesName[indexPath.row]

    cell.information.text = "liked your artwork"

            likesImage[indexPath.row].getDataInBackgroundWithBlock { (data, error) -> Void in

                if let downloadedImage = UIImage(data: data!) {

                    cell.artworkImage.image = downloadedImage

                }
            }

            likesAvatar[indexPath.row].getDataInBackgroundWithBlock { (data, error) -> Void in

                if let downloadedImage = UIImage(data: data!) {

                    cell.userAvatar.image = downloadedImage

                }
            }


    } else if indexPath.section == 1 {

        let cell = tableView.dequeueReusableCellWithIdentifier("toggleCell", forIndexPath:indexPath) as! RightToggleCell

        cell.userAvatar.layer.cornerRadius = cell.userAvatar.frame.size.width/2
        cell.userAvatar.clipsToBounds = true

        cell.artworkImage.contentMode = UIViewContentMode.ScaleAspectFill
        cell.artworkImage.clipsToBounds = true

        cell.artistName.text = commentsName[indexPath.row]

        cell.information.text = commentsInformation[indexPath.row]

            commentsImage[indexPath.row].getDataInBackgroundWithBlock { (data, error) -> Void in

                if let downloadedImage = UIImage(data: data!) {

                    cell.artworkImage.image = downloadedImage

                }
            }

            commentsAvatar[indexPath.row].getDataInBackgroundWithBlock { (data, error) -> Void in

                if let downloadedImage = UIImage(data: data!) {

                    cell.userAvatar.image = downloadedImage

                }
            }


    } else if indexPath.section == 2 {

        let cell = tableView.dequeueReusableCellWithIdentifier("toggleCell", forIndexPath:indexPath) as! RightToggleCell

        cell.userAvatar.layer.cornerRadius = cell.userAvatar.frame.size.width/2
        cell.userAvatar.clipsToBounds = true

        cell.artworkImage.contentMode = UIViewContentMode.ScaleAspectFill
        cell.artworkImage.clipsToBounds = true

        cell.artistName.text = bookmarksName[indexPath.row]

         cell.information.text = "bookmarked your artwork"

            bookmarksImage[indexPath.row].getDataInBackgroundWithBlock { (data, error) -> Void in

                if let downloadedImage = UIImage(data: data!) {

                    cell.artworkImage.image = downloadedImage

                }
            }

            bookmarksAvatar[indexPath.row].getDataInBackgroundWithBlock { (data, error) -> Void in

                if let downloadedImage = UIImage(data: data!) {

                    cell.userAvatar.image = downloadedImage

                }
            }
        }


    return cell

}

【问题讨论】:

    标签: swift tableview cell


    【解决方案1】:

    排列你的代码有点困难,但看起来你有:

    let cell = ...
    if ... {
        let cell = ...
    } else if ... {
        let cell = ...
    }
    return cell
    

    如果这是您所拥有的,则每个 if 内的 let cell 仅存在于该 if 内。因此,末尾的return cell 将返回初始的空单元格。如果是这种情况,您应该将其更改为:

    if ... {
        let cell = ...
        return cell
    } else if ... {
        let cell = ...
        return cell
    } else {
        let cell = ...
        return cell
    }
    

    请注意,最后一个条件必须是else 而不是else if,否则编译器会告诉您并非所有代码路径都返回一个值(当最后一个“if”失败时)。但是,您是说它基本上可以工作,所以有些事情没有意义。

    无论哪种方式,一旦一行移出屏幕,单元格就会重新用于新行。因此,当您的getDataInBackgroundWithBlock 返回时,该单元格可能属于不同的行。鉴于投影越来越暗,听起来您在 RightToggleCell 中有代码,当单元格被重用时会重新运行。

    在后台加载数据时,应将其存储在单元格之外,并在加载完成时重新加载该行。大致如下:

    likesImage[indexPath.row].getDataInBackgroundWithBlock { (data, error) -> Void in
        if let downloadedImage = UIImage(data: data!) {
            artworkImages[indexPath.row] = downloadedImage
            dispatch_async(dispatch_get_main_queue(), {
                tableView.reloadRowsAtIndexPaths([indexPath.row], withRowAnimation: true)
            })
        }
    }
    

    cellForRowAtIndexPath 应该显示相关的artifactImages(如果可用),否则使用上面的代码。请注意,UI 的任何更新都必须在主线程上完成,这就是上面调用 dispatch_async 的原因。

    【讨论】:

    • 我同样感到困惑。我填充的任何其他表都没有遇到这个问题。 RightToggleCell 不包含 IBOutlets 之外的任何内容。我切换了 cellForIndexRow 以返回 if let 语句中的每个单元格,但该函数仍然期望最后有一个返回函数
    • 有没有更好的方法来指定部分接收它的数据?每个部分中的单元格都能正确接收所有内容,但我不确定我构建它的方式是否会导致问题。
    【解决方案2】:

    建议您将此代码放入“RightToggleCell”中,而不是在 TableViewController 上执行所有操作。

    override func awakeFromNib() {
    
    self.userAvatar.layer.cornerRadius =  self.userAvatar.frame.size.width/2
    self.userAvatar.clipsToBounds = true
    
    self.artworkImage.contentMode = UIViewContentMode.ScaleAspectFill
    self.artworkImage.clipsToBounds = true
    
    }
    

    通过这样做,iOS 不会在每次重新加载 TableView 时修改cornerRadius 和 clipsToBounds

    【讨论】:

    • 感谢您的关注。我的项目中的其他所有东西都是这样设置的,不知道我是怎么错过的。我遇到了同样的问题。我所指的阴影实际上是一个图像。每次我上下滚动表格时,都会重新加载该图像和单元格中的所有其他内容。
    【解决方案3】:

    在 Michael 的指导下,我将返回单元格移到了每个 if let 语句中,并在语句之外返回了 UITableViewCell(),从而解决了问题。再次感谢迈克尔,我对你的回复投了赞成票,但我没有足够高的声誉来发布它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-04
      • 2016-01-15
      • 1970-01-01
      • 2013-10-15
      • 2016-06-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多