我在可重用的单元格旧图像显示中看到了类似的帖子,但仍然遇到相同的问题。本质上,我有一个TableView可以从Amazon s3下载图像,当您向下滚动时,一切正常,直到获得第12或第13张图像为止。发生的情况是,在下载新映像时,前一行中的映像在新行中显示大约2秒钟。这是我的代码(我仍然是快速学习IOS的新手)。stream_image_string是下载图像的完整URL,而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
}
}
任何建议都很好
您面临着一个非常常见的单元重用问题。当您使以前使用的单元出队时,该单元可能已经在其图像视图中安装了图像。在开始异步下载之前,将映像设置为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()
。该代码将在主线程上运行。
但是,您确实需要在DispatchQueue.main.async()
dataTask的完成处理程序内的代码周围进行第二个包装,因为URLSession
默认情况下,在后台队列上调用的完成处理程序。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句