Ios tableview中的图像加载另一个图像几秒钟
我在tableview中有一个从Json下载的图像,一切都很完美,但是在看到相应的图像之前滚动会加载另一个图像几秒钟(这些图像是表中已经可见的图像) 我的数据结构是:Ios tableview中的图像加载另一个图像几秒钟,ios,swift,uitableview,tableview,Ios,Swift,Uitableview,Tableview,我在tableview中有一个从Json下载的图像,一切都很完美,但是在看到相应的图像之前滚动会加载另一个图像几秒钟(这些图像是表中已经可见的图像) 我的数据结构是: struct Data: Decodable { let name: String let img: String let phone: String let linktaller: String let web: String } 加载图像的我的单元格的代码为:
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()
}
有关更多详细信息,请参见图:
欢迎您提出任何建议以解决此问题。因为当手机显示时,您可以通过以下方式从internet下载图像:
let data = try? Data(contentsOf: imageURL)
你应该
imageURL
中的图像是否已缓存import SDWebImage
imageView.sd_setImage(with: URL(string: "your_image_url"))
这是一个典型的单元重用问题。在开始下载之前,您应该在
tableView(cellForRowAt:)
方法中的每个单元格的图像视图中安装占位符图像或nil。这将清除安装到计算单元中的以前的映像,然后异步下载可以在后台运行,并在加载完成后安装映像。添加以下类以支持缓存映像:
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()
}
}
这样,图像的下载就可以正常工作了
在UITableViewdequeueReusableCell
中,每个UITableViewCell将使用不同的数据(图像)重复使用数次。
在您的情况下,每调用一个cellForRowAt
,就会从服务器加载映像,因此会有延迟。
解决方案:图像加载完成后,您必须在本地应用程序中使用url缓存图像。(1) -使用-支持缓存
(2) -您可以将图像保存在数组->中
cellForRowAt
如果存在则从此数组加载,如果不存在则从服务器加载
(来自互联网的图像)为了解决类似的问题,我修改了代码,以协调图像下载和tableView单元格的创建,并将图像存储在本地数组中。
我创建了一个字典数组来保存下载的图像,使用url字符串作为键:
imagesArray=[String:UIImage]()
然后,在代码中每个图像完成下载的地方,我将图像添加到数组中,并在tableView中插入一个新行:
updateValue(UIImage(数据:data!),forKey:imageURL为!字符串)
tableView.beginUpdate()
tableView.insertRows(位于:[IndexPath(行:imagesArray.count-1,节:0)],带:。自动)
tableView.endUpdates()
tableView.reloadData()
我还为每个图像维护一个单独的信息元素数组,包括作为一个元素的图像url字符串。这允许我在tableView单元格中显示正确的项目:
cell.itemNameLabel.text=itemRecords[indexPath.row].itemName
cell.itemImage.image=imagesArray[itemRecords[indexPath.row].imageURL]
在下载图像时,我提供了一个进度指示器微调器。
一旦图像全部下载并加载到imagesArray中,当用户上下滚动以查看列出的单元格时,将不会延迟显示,并且重新使用的单元格将加载正确的图像。
// Load image
let fimage = company[indexPath.row].img
ImageLoader.sharedInstance.imageForUrl(urlString: fimage, completionHandler: { (image, url) in
if image != nil {
cell.myImage.image = image
}
})