Background of problem: I am using Kingfisher to download and set images for all of my collection views and table views in my app. This works well, but I have one specific use case that I'm pretty sure Kingfisher doesn't have built in.
What I am trying to do: Download multiple images for a single collection view cell, and then update the cell with the images.
Why I am not using .kf.setImage(...)
: The collection view cell UI is all drawn from draw(_ rect: CGRect)
What I am doing now: In my UICollectionViewCell
I have an image array
var posters: [UIImage] = [] {
didSet {
setNeedsDisplay()
}
}
and I draw them into the cell
context.draw(image, in: CGRect(x: 0, y: -posterWindowFrame.minY, width: actualPosterWidth, height: actualPosterHeight))
In my view controller I load images in willDisplayCell:forItemAtIndexPath:
like so
override func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
let imageProviders = viewModel.imageProviders(at: indexPath)
var images = [UIImage]()
let group = DispatchGroup()
let cachedIndexPath = indexPath
imageProviders.forEach { provider in
guard let provider = provider else { return }
group.enter()
_ = KingfisherManager.shared.retrieveImage(with: .provider(provider), options: [.targetCache(posterCache)]) { result in
DispatchQueue.main.async {
defer {
group.leave()
}
switch result {
case .success(let imageResult):
images.append(imageResult.image)
case .failure:
print("No image available")
}
}
}
}
group.notify(queue: .main) {
guard
let cell = collectionView.cellForItem(at: cachedIndexPath) as? ListCollectionViewCell
else { return }
cell.posters = images
}
}
This works, but I can see the images changing (which could probably be fixed by pre-fetching) but I also notice a lot of lag when scrolling that I don't see when I comment this function out.
Besides fetching all of the images in ViewDidLoad
(or anywhere else, because of API rate limiting), how can I load these images in a way that doesn't cause lag and won't have problems with cell reuse?
EDIT - 8/13/19
I used UICollectionViewDataSourcePrefetching
to fetch the images and cache them locally, and then set the images in cellForRow
and it seems to work well for now.