5

I'm working with a UICollectionView with the default selection rules (single selection only). In my custom UICollectionViewCell class, I've overridden isSelected like so:

override var isSelected: Bool {
    didSet {
        self.backgroundColor = isSelected ? UIColor.gray : UIColor.white
    }
}

I also set isSelected for one specific cell in my view controller's collection​View(_:​cell​For​Item​At:​) because, for some reason, the collection's selectItem() method doesn't work in cellForItemAt.

This has allowed me to make sure that this one cell is selected and has its background changed before the entire view with the collection in it actually appears, but it's produced a weird problem.

When I start tapping other collection cells and selecting them, that one cell I set as selected from the start doesn't have its background color set to white.

However, as I proceed with selecting different cells in sequence by tapping them, the switching of their background colors to white happens just as intended, all the while that one cell where I set isSelected during the collection's initial population remains gray unless I specifically tap it and then tap away from it in a different cell.

Can anyone help me figure out why this is? Why isn't isSelected being set to false when I tap a cell other than the one whose isSelected property I set in cellForItemAt?

Edit: I tried implementing collection​View:​did​Deselect​Item​At​Index​Path:​, and it simply doesn't trigger. So on one hand, the isSelected property is definitely set, since the background for that one cell changes to gray, but on the other hand, the collection doesn't seem to perceive that cell as selected.

  • Provide the code of your `- collection​View(_:​cell​For​Item​At:​)` method. – nayem Mar 26 '17 at 05:06
  • Just the standard dequeueing of a cell and setting `cell.isSelected = true` based on a condition that definitely isn't interfering with this. The problem is that, for some reason, tapping and thus selecting other cells doesn't set `isSelected` for that initial cell to `false`, but does do so for all subsequently deselected cells. –  Mar 26 '17 at 05:44
  • 1
    Why did you explicitly set `cell.isSelected` to true? It's the job for the default implementation. Can you test commenting `cell.isSelected = true` in your code? – nayem Mar 26 '17 at 05:51
  • As I mentioned in my original post, I set the property because, for some reason unknown to me, the `collectionView.selectItem()` method doesn't work in `cellForItemAt`. So perhaps there's a larger scale mistake here that I'm not seeing, something to do with what the collection does after populating initially? –  Mar 26 '17 at 05:53
  • Maybe. But for that I've to take a look at your implementation. Better you look at my answer below for different workaround. I hope that'll help. – nayem Mar 26 '17 at 05:57
  • Figured it out. And in the process found a duplicate question about this exact issue, so going to flag this. Thanks for trying to help. –  Mar 26 '17 at 06:07
  • This works 100% - https://stackoverflow.com/a/67161317/11359553 – PAULMAX Apr 19 '21 at 11:46

1 Answers1

1

As you've edited your question, you can just use this approach.

// change background color when user touches cell
func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.backgroundColor = UIColor.gray
}

// change background color back when user releases touch
func collectionView(_ collectionView: UICollectionView, didUnhighlightItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.backgroundColor = UIColor.white
}
nayem
  • 7,285
  • 1
  • 33
  • 51