【发布时间】:2019-07-29 09:45:49
【问题描述】:
我正在从服务器下载图像并将其显示在collectionView 中。我正在缓存图像,以便用户获得快速的服务器响应并且 UI 中没有故障。在没有下载图片之前,我也添加了占位符图片。
但在我的输出中,图像正在其他单元格中复制,并且图像未正确缓存在 NSCache 中..
下面是代码
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
@IBOutlet weak var colView: UICollectionView!
var imageCache = NSCache<NSString, UIImage>()
var arrURLs = [
"https://homepages.cae.wisc.edu/~ece533/images/airplane.png",
"https://homepages.cae.wisc.edu/~ece533/images/arctichare.png",
"https://homepages.cae.wisc.edu/~ece533/images/baboon.png",
"https://homepages.cae.wisc.edu/~ece533/images/barbara.png",
"https://homepages.cae.wisc.edu/~ece533/images/boat.png",
"https://homepages.cae.wisc.edu/~ece533/images/cat.png",
"https://homepages.cae.wisc.edu/~ece533/images/fruits.png",
"https://homepages.cae.wisc.edu/~ece533/images/frymire.png",
"https://homepages.cae.wisc.edu/~ece533/images/girl.png",
"https://homepages.cae.wisc.edu/~ece533/images/goldhill.png",
"https://homepages.cae.wisc.edu/~ece533/images/lena.png",
"https://homepages.cae.wisc.edu/~ece533/images/monarch.png",
"https://homepages.cae.wisc.edu/~ece533/images/mountain.png",
"https://homepages.cae.wisc.edu/~ece533/images/peppers.png",
"https://homepages.cae.wisc.edu/~ece533/images/pool.png",
"https://homepages.cae.wisc.edu/~ece533/images/sails.png",
"https://homepages.cae.wisc.edu/~ece533/images/serrano.png",
"https://homepages.cae.wisc.edu/~ece533/images/tulips.png",
"https://homepages.cae.wisc.edu/~ece533/images/watch.png",
"https://homepages.cae.wisc.edu/~ece533/images/zelda.png"
]
func downloadImage(url: URL, imageView: UIImageView, placeholder : UIImage) {
imageView.image = placeholder // Set default placeholder..
// Image is set if cache is available
if let cachedImage = imageCache.object(forKey: url.absoluteString as NSString) {
imageView.image = cachedImage
} else {
// Reset the image to placeholder as the URLSession fetches the new image
imageView.image = placeholder
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard error == nil else {
// You should be giving an option to retry the image here
imageView.image = placeholder
return
}
if let respo = response as? HTTPURLResponse {
print("Status Code : ", respo.statusCode)
if let imageData = data, let image = UIImage(data: imageData) {
self.imageCache.setObject(image, forKey: url.absoluteString as NSString)
// Update the imageview with new data
DispatchQueue.main.async {
imageView.image = image
}
} else {
// You should be giving an option to retry the image here
imageView.image = placeholder
}
}
}.resume()
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let w = self.view.bounds.width - 30
return CGSize(width: w, height: w + 60)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return arrURLs.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "DummyCollectionViewCell", for: indexPath) as! DummyCollectionViewCell
let str = arrURLs[indexPath.item]
let url = URL(string: str)
downloadImage(url: url!) { (img) in
DispatchQueue.main.async {
cell.imgView.image = img ?? UIImage(named: "placeholder")
}
}
return cell
}
}
输出 GIF
由于堆栈大小限制,上述 gif 质量较低。如果您需要查看完整尺寸的 gif,请参考:https://imgur.com/tcjMWgc
【问题讨论】:
-
在
downloadImage方法的else语句中设置UIImageView的占位符 -
@CerlinBoss 你在哪一行?
-
我已将其添加为答案
-
你可以使用 SDWebImage 框架,它会为你做一切
-
@AlexandrKolesnik 这就是我想要学习如何使用 NSCache 的内容。你有任何关于这个问题的解决方案吗,因为我已经尝试了我在谷歌上找到的数百万种解决方案和组合。
标签: ios swift image-caching