IOS tableview在下载新图像时重复使用旧图像问题

时间:2017-05-05 23:47:19

标签: ios swift uitableview swift3 uiimage

我在Reusable cell old image showing阅读了类似的帖子,我仍然遇到同样的问题。基本上我有一个TableView,从亚马逊s3下载图像,当你向下滚动一切正常,直到你到达第12或第13张图像。发生的事情是,在下载新图像时,之前行中的图像显示在新行中约2秒钟。这是我的代码(我在swift和学习IOS时仍然是新手)。 stream_image_string 作为下载图片的完整网址, PicHeight 是一个以图片高度保存的整数,因为每个图片通常都有不同的高度。

var Stream_Cache = NSCache<AnyObject, AnyObject>()
  var stream_image_string = [String]()
    var PicHeight = [Int]()

下面是UITableViewCell,首先我检查是否有一个包含超过0个字符的url。然后我检查图像/网址是否保存在缓存中,如果没有,那么我下载它。

            if stream_image_string[indexPath.row].characters.count > 0 {
        if let image = Stream_Cache.object(forKey: stream_image_string[indexPath.row] as AnyObject) as? UIImage {
              DispatchQueue.main.async(execute: { () -> Void in
            cell.stream_image.image = image


            })
        } else {
            if cell.stream_image != nil {
            let strCellImageURL = self.stream_image_string[indexPath.row]
            let imgURL: NSURL = NSURL(string: strCellImageURL)!
        let request:NSURLRequest =  NSURLRequest(url: imgURL as URL)
        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config)

      cell.Stream_Image_Height.constant = CGFloat(Float(cell.pic_height!))
        let task = session.dataTask(with: request as URLRequest,    completionHandler: {(data, response, error) in
            DispatchQueue.main.async(execute: { () -> Void in

                if data != nil {
                cell.stream_image.image = UIImage(data: data!)
                } else {
                     cell.Stream_Image_Height.constant = 0
                    cell.stream_image.image = nil
                }


            })
        });

        task.resume()
            }
    }
    } else {

        cell.Stream_Image_Height.constant = 0
    }

在我的UITableViewCell文件中,我将图像设置为默认图像,以防它没有加载新图像但是它没有工作

class HomePageTVC: UITableViewCell {

    @IBOutlet weak var stream_image: UIImageView!

    var pic_height: Int?




    override func awakeFromNib() {
        super.awakeFromNib()
      stream_image.image = #imageLiteral(resourceName: "defaultImage")


    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

任何建议都会很棒

1 个答案:

答案 0 :(得分:4)

您面临着一个非常常见的细胞重用问题。当您将之前使用的单元格出列时,它可能已在其图像视图中安装了图像。在开始异步下载之前将图像设置为nil:

  if let imageString = stream_image_string[indexPath.row].characters,
      !imageString.isEmpty {
    if let image = Stream_Cache.object(forKey: imageString) as? UIImage {
      cell.stream_image.image = image
    } else {
      //Clear out any old image left in the recycled image view.
      cell.stream_image.image = nil
      //Your code to download the image goes here
    }
  }

请注意,在cell.stream_image.image = image的调用中无需包含DispatchQueue.main.async()代码。该代码将在主线程上运行。

,但是,需要围绕dataTask的completionHandler中的代码的第二个DispatchQueue.main.async()包装器,因为URLSession的完成处理程序是默认情况下调用后台队列。