I have a trouble with method "didDeselectItemAt" in collection view.
App: i have a collection with cells(see screenshot). User can to highlight only one cell.
when the user clicks on one cell, it is highlighted. when he click on another one, another one is selected, and the previous one becomes normal.
and when I select, for example, the first cell, and then the last one, the first one remains selected.
empirically, I found out that this problem. happens when, after the first one, I click on a cell that is out of view while clicking on the first one (you need to scroll)
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if collectionView == albumsCollectionView {
guard let cell = collectionView.cellForItem(at: indexPath) as? AlbumCollectionCell else { return }
cell.isCellSelected()
presenter?.didChooseAlbum(with: indexPath.row) {
self.picturesCollectionView.reloadData()
}}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
if collectionView == albumsCollectionView {
guard let cell = collectionView.cellForItem(at: indexPath) as? AlbumCollectionCell else { return }
cell.isCellDeselected()
}
}
2
Answers
As @DonMag mentioned in the comment, you have to track selected state in your data source. Here are the steps.
As you are showing some data in cell, you can make a model for it.
In
AlbumCollectionCell
addAlbum
type variable. And override theisSelected
property ofUICollectionViewCell
In
UIViewController
, create an array ofAlbum
type which holds the data of cells. You may assign the data inviewDidLoad()
method.Set
allowsSelection
property ofUICollectionView
totrue
.In
cellForItem
method pass theAlbum
data to cell.Modify didSelectItem method like below.
And override
didDeselectItemAt
method.If you are trying to persist the selection – that is, if you want to save it and restore the last selection between app uses, or if you’re navigating away and you want to restore it when navigating again to that controller – then you need to track it with your data source.
However, if you’re not concerned with persistence, you can let the collection view handle it.
In your cell class, override
isSelected
:Now, you don’t need any "cell appearance" code in
didSelectItemAt
or indidDeselectItemAt
… the collection view will manage the selected state.Here’s a quick, complete example…
Custom Cell class
Example Controller class