Ios UICollectionViewCell图像在API调用后重新加载问题
我正在尝试加载URL所在的特定单元格的图像。具有下载图像并通过回调方法发送的函数,但回调后,其他单元格也会被下载的图像加载。谢谢你 下面是代码示例。在方法Ios UICollectionViewCell图像在API调用后重新加载问题,ios,swift,uitableview,Ios,Swift,Uitableview,我正在尝试加载URL所在的特定单元格的图像。具有下载图像并通过回调方法发送的函数,但回调后,其他单元格也会被下载的图像加载。谢谢你 下面是代码示例。在方法cellForItemAtIndexPath 让stationCollectionViewcell:stationCollectionViewcell=collectionView.DequeueReuseAbleCell(使用ReuseIdentifier:“stationCell”,for:indexPath)作为!StationColle
cellForItemAtIndexPath
让stationCollectionViewcell:stationCollectionViewcell=collectionView.DequeueReuseAbleCell(使用ReuseIdentifier:“stationCell”,for:indexPath)作为!StationCollectionViewCell
如果imageURL.contains(“http”){
self.loadImageWithURL(url:url(字符串:station.imageURL)!){(图像)在
stationCollectionViewcell.RadioMgView.image=图像
}
}否则,如果imageURL!="" {
stationCollectionViewcell.RadioMgView.image=UIImage(名为:“station therockfm”)
}否则{
stationCollectionViewcell.RadioMgView.image=UIImage(名为:“stationImage”)
}
以及下载图像的功能
func loadImageWithURL(url:url,回调:@escaping(UIImage)->()){
打印(“这是正在执行的loadImageWithURL”)
让session=URLSession.shared
让downloadTask=session.downloadTask(带url,completionHandler:{
url、响应、中的错误
如果错误==nil&&url!=nil{
如果let data=NSData(contentsOf:url!){
如果let image=UIImage(数据:数据作为数据){
DispatchQueue.main.async(执行:{
回调(图像)
})
}
}
}
})
downloadTask.resume()
}
每次单元都在重复使用,控制器中也有异步调用。在下载完成过程中,需要通过indepath
重新加载单元格
另外,在prepareforeuse
override func prepareForReuse() {
super.prepareForReuse()
stationCollectionViewcell.radioImgView.image = nil
}
异步映像的最佳解决方案是使用缓存
let imageCache: NSCache<NSString, UIImage> = NSCache<NSString, UIImage>()
下一次,当单元格出现时,检查图像是否已存在于imageCache
如果是,请使用缓存中的映像;如果不是,请下载映像
代码应该如下所示:
if imageURL.contains("http") {
if let image = imageCache.object(forKey: station.imageURL as NSString) {
stationCollectionViewcell.radioImgView.image = image
} else {
self.loadImageWithURL(url: URL(string: station.imageURL)!) { [weak self] (image) in
self?.imageCache.setObject(image, forKey: url as NSString)
self?.collectionView.collectionView.reloadItems(at: [indexPath])
}
}
} else if imageURL != "" {
stationCollectionViewcell.radioImgView.image = UIImage(named: "station-therockfm")
} else {
stationCollectionViewcell.radioImgView.image = UIImage(named: "stationImage")
}
在重新使用单元格之前,您应该重置
图像
,因为在下载新的单元格之前,它会与以前的图像一起重新使用。另外,您应该将保存的url和回调中的url进行比较,因为当单元格被重用时,回调可能会返回
// reset image
override func prepareForReuse() {
super.prepareForReuse()
radioImgView.image = nil // set nil or default image
}
将url添加到回调
func loadImageWithURL(url: URL, callback: @escaping (UIImage, URL) -> ()) {
print("This is getting excuted loadImageWithURL")
let session = URLSession.shared
let downloadTask = session.downloadTask(with: url, completionHandler: {
url, response, error in
if error == nil && url != nil {
if let data = NSData(contentsOf: url!) {
if let image = UIImage(data: data as Data) {
DispatchQueue.main.async(execute: {
callback(image, url!)
})
}
}
}
})
downloadTask.resume()
}
比较url
let stationCollectionViewcell : StationCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "stationCell", for: indexPath) as! StationCollectionViewCell
if imageURL.contains("http") {
let url = URL(string: station.imageURL)!
self.loadImageWithURL(url: url) { (image, callbackUrl) in
guard url == callbackUrl else { return }
stationCollectionViewcell.radioImgView.image = image
}
} else if imageURL != "" {
stationCollectionViewcell.radioImgView.image = UIImage(named: "station-therockfm")
} else {
stationCollectionViewcell.radioImgView.image = UIImage(named: "stationImage")
}
我希望它会运行良好。
import UIKit
let imageCache = NSCache<AnyObject, AnyObject>()
class CustomImageView : UIImageView {
var imgUrlString : String?
func loadImageWithURL(urlString : String) {
imgUrlString = urlString
guard let url = URL(string: urlString) else { return }
image = nil
if let imgFromCache = imageCache.object(forKey: urlString as AnyObject) as? UIImage {
self.image = imgFromCache
return
}
URLSession.shared.dataTask(with: url) { (data, resposne, error) in
if error != nil {
print(error)
return
}
DispatchQueue.main.sync {
let imageToCache = UIImage(data: data!)
imageCache.setObject(imageToCache!, forKey: urlString as AnyObject)
if self.imgUrlString == urlString {
self.image = imageToCache
}
}
}.resume()
}
}
细胞被重复使用。首先将
radiomgview.image
重置为nil
(或占位符)。@Larme尝试了此操作,但没有成功,请给出一些示例。
import UIKit
let imageCache = NSCache<AnyObject, AnyObject>()
class CustomImageView : UIImageView {
var imgUrlString : String?
func loadImageWithURL(urlString : String) {
imgUrlString = urlString
guard let url = URL(string: urlString) else { return }
image = nil
if let imgFromCache = imageCache.object(forKey: urlString as AnyObject) as? UIImage {
self.image = imgFromCache
return
}
URLSession.shared.dataTask(with: url) { (data, resposne, error) in
if error != nil {
print(error)
return
}
DispatchQueue.main.sync {
let imageToCache = UIImage(data: data!)
imageCache.setObject(imageToCache!, forKey: urlString as AnyObject)
if self.imgUrlString == urlString {
self.image = imageToCache
}
}
}.resume()
}
}
let thumbnailImageView : CustomImageView = {
let imgView = CustomImageView()
imgView.translatesAutoresizingMaskIntoConstraints = false
imgView.image = #imageLiteral(resourceName: "taylor_swift_blank_space")
imgView.contentMode = .scaleAspectFill
imgView.clipsToBounds = true
return imgView
}()