Deselect UICollectionView cell on second tap
Try using the "shouldSelectItem" UIColllectionViewDelegate method.
func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
let item = collectionView.cellForItem(at: indexPath)
if item?.isSelected ?? false {
collectionView.deselectItem(at: indexPath, animated: true)
} else {
collectionView.selectItem(at: indexPath, animated: true, scrollPosition: [])
return true
}
return false
}
A shorter version of @pkorosec answer, with exact the same effect, is the following:
override func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
if collectionView.cellForItem(at: indexPath)?.isSelected ?? false {
collectionView.deselectItem(at: indexPath, animated: true)
return false
}
return true
}
An alternative, suggested by @Manav, is:
override func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
if collectionView.indexPathsForSelectedItems?.contains(indexPath) ?? false {
collectionView.deselectItem(at: indexPath, animated: true)
return false
}
return true
}
Another option, that I personally think is way cleaner, is to allow multiple selection on collection view and then manually deselect the currently selected item before next selection.
First step: allow multiple selection
override func viewDidLoad() {
super.viewDidLoad()
collectionView.allowsMultipleSelection = true
}
Second step: manually deselect previously selected item
func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
collectionView.indexPathsForSelectedItems?.forEach { ip in
collectionView.deselectItem(at: ip, animated: true)
}
return true
}