我在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
}
}
任何建议都会很棒
答案 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
的完成处理程序是默认情况下调用后台队列。