从服务器下载图像时, Collection View 单元格中的图像不会更新。滚动 Collection View 时图像会更新。
TableView 的每个部分都有一个 Collection View 。表格 View 单元格具有 Collection View 的数据源。
extension OffersCell: UICollectionViewDataSource,UICollectionViewDelegate{
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return photoViewModel.photos.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "photoCell", for: indexPath)
(cell as! PhotoCell).imageView.contentMode = .scaleAspectFill
return cell
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
let photo = self.photoViewModel.photos[indexPath.row]
(cell as! PhotoCell).imageView.image = UIImage(named: "dummyImage")
ImageDownloadManager.shared.downloadImage(photo, indexPath: indexPath) { (image, imageIndexPath, error) in
if let indexPathNew = imageIndexPath, indexPathNew == indexPath {
DispatchQueue.main.async {
(cell as! PhotoCell).imageView.image = image
}
}
}
}
}
请找到图片下载器类:
typealias ImageDownloadHandler = (_ image: UIImage?, _ indexPath: IndexPath?, _ error: Error?) -> Void
final class ImageDownloadManager {
private var completionHandler: ImageDownloadHandler?
lazy var imageDownloadQueue: OperationQueue = {
var queue = OperationQueue()
queue.name = "imageDownloadQueue"
queue.qualityOfService = .userInteractive
return queue
}()
let imageCache = NSCache<NSString, UIImage>()
static let shared = ImageDownloadManager()
private init () {}
func downloadImage(_ photo: Photos, indexPath: IndexPath?, handler: @escaping ImageDownloadHandler) {
self.completionHandler = handler
guard let url = photo.getImageURL() else {
return
}
if let cachedImage = imageCache.object(forKey: photo.id as NSString) {
self.completionHandler?(cachedImage, indexPath, nil)
} else {
let operation = CustomOperation(url: url, indexPath: indexPath)
if indexPath == nil {
}
operation.queuePriority = .high
operation.downloadHandler = { (image, indexPath, error) in
if let newImage = image {
self.imageCache.setObject(newImage, forKey: photo.id as NSString)
}
self.completionHandler?(image, indexPath, error)
}
imageDownloadQueue.addOperation(operation)
}
}
func cancelAll() {
imageDownloadQueue.cancelAllOperations()
}
}
最佳答案
下载图像后,在主线程上执行指令 (cell as! PhotoCell).imageView.image = image
。但这不会重新显示您的 collectionView 单元格。
此外,通常不会调用 collectionView:willDisplayCell:forItemAtIndexPath:
。 docs说
The collection view calls this method before adding a cell to its content.
然而,当您在单元格中滚动时,即当它变得可见时,它会被调用。这就是为什么在单元格滚动后显示图像的原因。
所以我的建议是:
- 下载图像后,更新您的 collectionView 数据源
以便
collectionView:cellForItemAtIndexPath:
可以配置单元格 与图像。 - 调用
reloadItems(at:)
使用一个仅包含更新单元格索引路径的数组。
关于ios - 异步下载图像时, Collection View 单元格中的图像不会更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57970876/