I am learning ios coding and reading a book. There is something about the indexPath of a UICollectionViewCell that I don't understand. The UICollectionView displays images that are fetched using the remoteUrl attribute of the Photo Object with URLSessionDataTask. An escaping compeletion handler is passed to the image-fetching function to update the UIImageView inside the cell.
The comment of the code snippet on the book says that "The index path for the photo might have changed between the time the request started and finished". Why does that happen?
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
let photo = photoDataSource.photos[indexPath.row]
// Download the image data, which could take some time
photoStore.fetchImage(photo: photo) { (result) in
// The index path for the photo might have changed between the
// time the request started and finished, so find the most
// recent index path
guard
let photoIndex = self.photoDataSource.photos.firstIndex(of: photo),
case let .success(image) = result
else {
return
}
let photoIndexPath = IndexPath(row: photoIndex, section: 0)
// When the request finishes, only update the cell if it's still visible
if let cell = collectionView.cellForItem(at: photoIndexPath) as? PhotoCollectionViewCell {
cell.updateImage(image: image)
}
}
}
Read about reuse cell for tableView, or for collectionView
Example:
add code
In viewDidLoad
:
collectionView.register(UICollectionViewCell.self, forCellReuseIdentifier: "Your Reuse Identifier")
In Extension
of your viewController (UICollectionViewDelegateFlowLayout)
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Your Reuse Identifier", for: indexPath)
cell.imageView.image = photos[indexPath.row]
return cell
}