【发布时间】:2018-03-23 05:33:01
【问题描述】:
我有一个自定义 UICollectionViewCell 定义如下:
class MomentsCell: UICollectionViewCell {
@IBOutlet weak var imageView: UIImageView!}
我的委托方法如下所示:
override func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier,
for: indexPath) as! MomentsCell
let imageURL = imageURLS[indexPath.row]
self.updateImageForCell(cell: cell,
inCollectionView: collectionView,
withImageURL: imageURL,
atIndexPath: indexPath)
return cell
方法“updateImageForCell”如下所示:
func updateImageForCell(cell: MomentsCell,
inCollectionView collectionView: UICollectionView,
withImageURL: String,
atIndexPath indexPath: IndexPath) {
/*if let url = URL(string: withImageURL) {
cell.imageView.setImageWith(url, placeholderImage: UIImage(named: "placeholder"))
}*/
cell.imageView.image = UIImage(named: "placeholder")
ImageManager.shared.downloadImageFromURL(withImageURL) {
(success, image) -> Void in
if success && image != nil {
// checks that the view did not move before setting the image to the cell!
if collectionView.cellForItem(at: indexPath) == cell {
cell.imageView.image = image
}
}
}
}
ImageManager 是一个单例,其中包含一组图像的缓存。如果图像 URL 在缓存中,则返回缓存的图像。如果没有,它会启动一个 URLSession 从 Firebase 下载图像。
第一次加载视图时,图像确实会显示出来,这向我表明,此时一切都或多或少地正常工作。但是,当我滚动时,会加载随机图像,有些最终没有加载,最终所有单元格都变为空白并且无论如何都不会加载,即使所有内容都保存在缓存中。
这很糟糕,但这是我的 ImageManager 类:
class ImageManager: NSObject {
static var shared: ImageManager { return _singletonInstance }
var imageCache = [String : UIImage]()
// checks the local variable for url string to see if the UIImage was already downloaded
func cachedImageForURL(_ url: String) -> UIImage? {
return imageCache[url]
}
// saves a downloaded UIImage with corresponding URL String
func cacheImage(_ image: UIImage, forURL url: String) {
// First check to see how many images are already saved in the cache
// If there are more images than the max, we have to clear old images
if imageCache.count > kMaxCacheImageSize {
imageCache.remove(at: imageCache.startIndex)
}
// Adds the new image to the END of the local image Cache array
imageCache[url] = image
}
func downloadImageFromURL(_ urlString: String,
completion: ((_ success: Bool,_ image: UIImage?) -> Void)?) {
// First, checks for cachedImage
if let cachedImage = cachedImageForURL(urlString) {
completion?(true, cachedImage)
} else {
guard let url = URL(string: urlString) else {
completion?(false,nil)
return
}
print("downloadImageFromURL")
let task = URLSession.shared.downloadTask(with: url,
completionHandler: { (url, response, error) in
print("downloadImageFromURL complete")
if error != nil {
print("Error \(error!.localizedDescription)")
} else {
if let url = URL(string: urlString),
let data = try? Data(contentsOf: url) {
if let image = UIImage(data: data) {
self.cacheImage(image, forURL: url.absoluteString)
DispatchQueue.main.async(execute: { completion?(true, image) })
}
}
}
})
task.resume()
}
}
func prefetchItem(url urlString: String) {
guard let url = URL(string: urlString) else {
return
}
let task = URLSession.shared.downloadTask(with: url,
completionHandler: { (url, response, error) in
if error != nil {
print("Error \(error!.localizedDescription)")
} else {
if let url = URL(string: urlString),
let data = try? Data(contentsOf: url) {
if let image = UIImage(data: data) {
self.cacheImage(image, forURL: url.absoluteString)
}
}
}
})
task.resume()
}
}
任何帮助将不胜感激。如果我错过了任何重要信息,请告诉我。
【问题讨论】:
标签: ios swift uicollectionview uicollectionviewcell