So the crash is happening because when selecting an item, didDeselectItemAt
can be called for an item that's not visible anymore.
The UICollectionView
reuses UICollectionViewCells
, this means that the collectionView.cellForItem(at: indexPath)
method will return nil for cells that are not visible.
To fix this you can use the following code:
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
guard let cell = collectionView.cellForItem(at: indexPath) as! ImageCollectionViewCell else {
return //the cell is not visible
}
UIView.animate(withDuration: 0.3, animations: {
cell.imageView.alpha = 0.6
})
}
Some other suggestions I have for improving your code:
You have a lot of places where you're force unwrapping values.
Consider taking the following approach:
guard let url = self.collection?.imageUrls?[indexPath.row] else {
fatalError("url was nil")
}
self.selectedImageUrl = url
Alamofire.request(url).responseImage(completionHandler: {
(response) in
if response.result.value != nil {
self.selectedImage.image = response.result.value
}
})
By using the guard statement you force the app to crash with an appropriate error message, which will help you when debugging. It's a better practice compared to force unwrapping.
Also, when dequeing cells, you could go for something like this:
let cellIdentifier = "ImageCell"
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as? ImageCollectionViewCell else {
fatalError("Wrong cell type")
}
This can happen when the cell type is different