Upon cell selection, I want to handle changing the cell appearance. I figured the delegate method collectionView:didSelectItemAtIndexPath:
& collectionView:didDeselectItemAtIndexPath:
is where I should edit the cell.
-(void)collectionView:(UICollectionView *)collectionView
didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
DatasetCell *datasetCell =
(DatasetCell *)[collectionView cellForItemAtIndexPath:indexPath];
[datasetCell replaceHeaderGradientWith:[UIColor skyBlueHeaderGradient]];
datasetCell.backgroundColor = [UIColor skyBlueColor];
}
and
-(void)collectionView:(UICollectionView *)collectionView
didDeselectItemAtIndexPath:(NSIndexPath *)indexPath {
DatasetCell *datasetCell =
(DatasetCell *)[collectionView cellForItemAtIndexPath:indexPath];
[datasetCell replaceHeaderGradientWith:[UIColor grayGradient]];
datasetCell.backgroundColor = [UIColor myDarkGrayColor];
}
This works fine, except when the cell gets reused. If I select cell at index (0, 0), it changes the appearance but when I scroll down, there is another cell in the selected state.
I believe I should use the UICollectionViewCell
method -(void)prepareForReuse
to prep the cell for resuse (ie, set the cell appearance to non selected state) but its giving me difficulties.
-(void)prepareForReuse {
if ( self.selected ) {
[self replaceHeaderGradientWith:[UIColor skyBlueHeaderGradient]];
self.backgroundColor = [UIColor skyBlueColor];
} else {
[self replaceHeaderGradientWith:[UIColor grayGradient]];
self.backgroundColor = [UIColor myDarkGrayColor];
}
}
When I scroll back to the top, the cell at index (0, 0) is in the deselected state.
When I just used the cell.backgroundView property, to prevent this from happening was to:
-(void)prepareForReuse {
self.selected = FALSE;
}
and the selection state worked as intended.
Any ideas?
Thanks to your answer @RDC.
The following codes works with Swift 3
Anil was on the right track (his solution looks like it should work, I developed this solution independently of his). I still used the
prepareForReuse:
method to set the cell'sselected
toFALSE
, then in thecellForItemAtIndexPath
I check to see if the cell's index is in `collectionView.indexPathsForSelectedItems', if so, highlight it.In the custom cell:
In
cellForItemAtIndexPath:
to handle highlighting and dehighlighting reuse cells:And then handle cell highlighting and dehighlighting in the
didDeselectItemAtIndexPath:
anddidSelectItemAtIndexPath:
This works like a charm for me.
Framework will handle switching the views for you once you setup your cell's
backgroundView
andselectedBackgroundView
, see example from Managing the Visual State for Selections and Highlights:you only need in your class that implements
UICollectionViewDelegate
enable cells to be highlighted and selected like this:This works me.
In your custom cell create public method:
Also write redefenition of -prepareForReuse cell method:
And in your ViewController you should have _selectedIndexPath variable, which defined in -didSelectItemAtIndexPath and nullified in -didDeselectItemAtIndexPath
UICollectionView has changed in iOS 10 introducing some problems to solutions above.
Here is a good guide: https://littlebitesofcocoa.com/241-uicollectionview-cell-pre-fetching
Cells now stay around for a bit after going off-screen. Which means that sometimes we might not be able to get hold of a cell in
didDeselectItemAt indexPath
in order to adjust it. It can then show up on screen un-updated and un-recycled.prepareForReuse
does not help this corner case.The easiest solution is disabling the new scrolling by setting
isPrefetchingEnabled
to false. With this, managing the cell's display withcellForItemAt
didSelect
didDeselect
works as it used to.However, if you'd rather keep the new smooth scrolling behaviour it's better to use
willDisplay
:With the above you control the cell when it's selected, unselected on-screen, recycled, and just re-displayed.
you can just set the selectedBackgroundView of the cell to be backgroundColor=x.
Now any time you tap on cell his selected mode will change automatically and will couse to the background color to change to x.