tableview中的图像会加载另一个图像几秒钟
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了tableview中的图像会加载另一个图像几秒钟相关的知识,希望对你有一定的参考价值。
我在tableview中有一个从Json下载的图像,一切都很完美,但在看到相应图像之前滚动它会加载另一个图像几秒钟(这些图像是表中已经可见的图像)。
我的数据结构是:
struct Data: Decodable {
let name: String
let img: String
let phone: String
let linktaller: String
let web: String
}
我的单元格中加载图像的代码是:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as? AseguradorasTableViewCell else { return UITableViewCell() }
cell.titleLbl.text = company[indexPath.row].name
.
.
.
// load image
if let imageURL = URL(string: company[indexPath.row].img) {
DispatchQueue.global().async {
let data = try? Data(contentsOf: imageURL)
if let data = data {
let image = UIImage(data: data)
DispatchQueue.main.async {
cell.myImage.image = image
}
}
}
}
return cell
}
加载数据的功能是:
func downloadJSON() {
let url = URL(string: "http://myserver.com/data.json")
URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error == nil {
do {
self.company = try JSONDecoder().decode([Data].self, from: data!)
print(self.company)
DispatchQueue.main.async {
self.tableView.reloadData()
self.refreshControl.endRefreshing()
}
} catch let jsonError{
print("error + (jsonError)")
}
}
}.resume()
}
查看图片了解更多详情:
欢迎任何建议来解决这个问题。
为缓存映像支持添加以下类:
class ImageLoader {
var cache = NSCache<AnyObject, AnyObject>()
class var sharedInstance : ImageLoader {
struct Static {
static let instance : ImageLoader = ImageLoader()
}
return Static.instance
}
func imageForUrl(urlString: String, completionHandler:@escaping (_ image: UIImage?, _ url: String) -> ()) {
let data: NSData? = self.cache.object(forKey: urlString as AnyObject) as? NSData
if let imageData = data {
let image = UIImage(data: imageData as Data)
DispatchQueue.main.async {
completionHandler(image, urlString)
}
return
}
let downloadTask: URLSessionDataTask = URLSession.shared.dataTask(with: URL.init(string: urlString)!) { (data, response, error) in
if error == nil {
if data != nil {
let image = UIImage.init(data: data!)
self.cache.setObject(data! as AnyObject, forKey: urlString as AnyObject)
DispatchQueue.main.async {
completionHandler(image, urlString)
}
}
} else {
completionHandler(nil, urlString)
}
}
downloadTask.resume()
}
}
在单元格中,按如下方式加载图像:
// Load image
let fimage = company[indexPath.row].img
ImageLoader.sharedInstance.imageForUrl(urlString: fimage, completionHandler: { (image, url) in
if image != nil {
cell.myImage.image = image
}
})
这样,图像的下载应该可以正常工作
在UITableView中,dequeueReusableCell
-每个UITableViewCell将使用不同的数据(图像)重复使用几次。在你的情况下,每个cellForRowAt
被调用,图像将从服务器加载,因此它将有延迟。解决方案:当图像加载完成时,您必须使用本地应用程序中的URL缓存图像。
(1) - 使用SDWebImage - 缓存支持
(2) - 您可以将图像保存在数组中 - >在cellForRowAt
中从此数组加载(如果存在)并从服务器加载(如果不存在)
(来自互联网的图片)
由于电池何时显示,您可以从互联网上下载图像
let data = try? Data(contentsOf: imageURL)
你应该
- 检查
imageURL
中的图像是否已缓存 - 如果缓存,则从本地加载图像
- 如果没有缓存,请从Internet下载,然后缓存它。
或者只是简单地使用SDWebImage或其他任何东西,它会自动检查您的步骤1到3:D
例如,通过使用SDWebImage
import SDWebImage
imageView.sd_setImage(with: URL(string: "your_image_url"))
这是一个经典的细胞重用问题。在开始下载之前,您应该在tableView(cellForRowAt:)
方法的每个单元格的图像视图中安装占位符图像或nil。这将清除安装在单元格中的先前图像,然后异步下载可以在后台运行并在加载完成后安装图像。
为了解决类似的问题,我改变了我的代码,通过创建tableView单元来协调下载图像,将图像存储在本地数组中。 我创建了一个字典数组来保存下载的图像,使用url字符串作为键: imagesArray = [String:UIImage]() 然后,在每个图像完成下载的代码中,我将图像添加到数组并在tableView中插入一个新行: imagesArray.updateValue(UIImage(data:data!)!,forKey:imageURL as!String) tableView.beginUpdates() tableView.insertRows(at:[IndexPath(row:imagesArray.count-1,section:0)],with:。autoo) tableView.endUpdates() tableView.reloadData() 我还为每个图像维护一个单独的信息元素数组,包括图像url字符串作为一个元素。这允许我在tableView单元格中显示正确的项目: cell.itemNameLabel.text = itemRecords [indexPath.row] .itemName cell.itemImage.image = imagesArray [itemRecords [indexPath.row] .imageURL] 在下载图像时,我提供了一个进度指示器微调器。 一旦图像全部下载并加载到imagesArray中,当用户向上和向下滚动以查看列出的单元格时,呈现没有延迟,并且重用的单元格加载有正确的图像。
以上是关于tableview中的图像会加载另一个图像几秒钟的主要内容,如果未能解决你的问题,请参考以下文章
UITableView 中的 UIImage 显示另一个单元格的图像一秒钟