UICollectionView shouldSelectItemAtIndexPath=NO does not avoid deselecting old selection?

sust86 picture sust86 · Jan 23, 2013 · Viewed 17.3k times · Source

I have multiple items in a CollectionView, but only a few of them should be selectable. I'm handling this with the delegate method:

- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath

My problem occurs if a selectable item is selected and in the next step the selection of a not selectable item is rejected by shouldSelectItemAtIndexPath returning NO, the selected item gets deselected anyway.

I have also tried to use

- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath

But it's the same problem.

Is this the correct desired behaviour of UICollectionView? And if yes, how can i avoid the deselection of my last selected item if a not selectable item gets selected?

Answer

sust86 picture sust86 · Jan 23, 2013

I have to correct my assumption: The last selection won't get deselected!

In order to change the appearance of the cell on selection I have overridden the setSelected accessor of UICollectionViewCell. When selecting a non selectable item, the accessor setSelected of the last selected cell gets called multiple times. First with the state NO, then with the state YES and in the end with NO again. The last state NO caused my cell to set its appearance to that of an non selected cell.

I don't know the reason for this weird behavior nor could i solve it.

My workaround is to change the appearance of selected cells directly in the ViewController.

Set the selected appearance in:

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath

Remove the selected appearance:

- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath

Check if the current cell is selected and change the appearance as intended.

   - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath