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()
}
}
CodePudding user response:
Try with UITapGestureRecognizer, in cellForItemAt add gesture to cell contentView:
let gesture = UITapGestureRecognizer(target: self, action: #selector(self.isCellDeselected))
cell.contentView.addGestureRecognizer(gesture)
add your tapGesture func
@objc func isCellDeselected() {
print("This Is your cell")
}
CodePudding user response:
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.
struct Album {
let name: String
var isSelected: Bool
}
In AlbumCollectionCell
add Album
type variable. And override the isSelected
property of UICollectionViewCell
class AlbumCollectionCell: UICollectionViewCell {
var album: Album? {
didSet {
guard let shoe = shoe else { return }
self.shoeSize?.text = shoe.size
if shoe.isSelected {
self.backgroundColor = UIColor.orange
}
else {
self.backgroundColor = UIColor.green
}
self.albumLabel.textColor = .white
self.albumLabel.text = album.name
}
}
override var isSelected: Bool {
didSet {
if self.isSelected {
self.backgroundColor = UIColor.orange
}
else {
self.backgroundColor = UIColor.green
}
}
}
}
In UIViewController
, create an array of Album
type which holds the data of cells. You may assign the data in viewDidLoad()
method.
var albums = [Album]()
Set allowsSelection
property of UICollectionView
to true
.
collectionView.allowsSelection = true
In cellForItem
method pass the Album
data to cell.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "AlbumCollectionCell", for: indexPath) as? AlbumCollectionCell {
cell.album = albums[indexPath.item]
return cell
}
return UICollectionViewCell()
}
Modify didSelectItem method like below.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
albums[indexPath.item].isSelected = true
}
And override didDeselectItemAt
method.
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
albums[indexPath.item].isSelected = false
}