Where to highlight UICollectionViewCell: delegate or cell? Where to highlight UICollectionViewCell: delegate or cell? ios ios

Where to highlight UICollectionViewCell: delegate or cell?


As the documentation says, you can rely on highlighted property to be changed while the cell is highlighted. For example the following code will make the cell red when highlighted (not its subviews though):

- (void)setHighlighted:(BOOL)highlighted {    [super setHighlighted:highlighted];    [self setNeedsDisplay];}- (void)drawRect:(CGRect)rect {    [super drawRect:rect];    if (self.highlighted) {        CGContextRef context = UIGraphicsGetCurrentContext();        CGContextSetRGBFillColor(context, 1, 0, 0, 1);        CGContextFillRect(context, self.bounds);    } }

And if you add something like this the background will become purple (red + opaque blue):

- (void)collectionView:(UICollectionView *)colView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath {    UICollectionViewCell *cell = [colView cellForItemAtIndexPath:indexPath];    cell.contentView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:1 alpha:0.5];}- (void)collectionView:(UICollectionView *)colView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath {    UICollectionViewCell *cell = [colView cellForItemAtIndexPath:indexPath];    cell.contentView.backgroundColor = nil;}

So you can use both together (not necessarily both changing the cell appearance). The difference is that with delegate methods you also have indexPath. It might be used to create multi-selection (you will use this methods together with selection delegate methods), to show some preview while the cell is highlighted, to show some animation with other views... There's quite a few appliance for this delegate methods in my opinion.

As a conclusion, I would leave the cell appearance to be handled by the cell itself and use delegate methods to let controller make something cool in the same time.


Two possible approaches are outlined below.

Cell Subclassing

Cleaner approach if already subclassing from UICollectionViewCell.

class CollectionViewCell: UICollectionViewCell {    override var highlighted: Bool {        didSet {            self.contentView.backgroundColor = highlighted ? UIColor(white: 217.0/255.0, alpha: 1.0) : nil        }    }}

UICollectionViewDelegate

Less clean, requires the collection view delegate to know about the presentation logic of the cells.

func collectionView(collectionView: UICollectionView, didHighlightItemAtIndexPath indexPath: NSIndexPath) {    if let cell = collectionView.cellForItemAtIndexPath(indexPath) {        cell.contentView.backgroundColor = UIColor(white: 217.0/255.0, alpha: 1.0) // Apple default cell highlight color    }}func collectionView(collectionView: UICollectionView, didUnhighlightItemAtIndexPath indexPath: NSIndexPath) {    if let cell = collectionView.cellForItemAtIndexPath(indexPath) {        cell.contentView.backgroundColor = nil    }}


Notice that UICollectionViewCell has a selectedBackgroundView property. By default, it's nil. Just create a view for this property, and it will appear when the user touches the cell.

override func awakeFromNib() {    super.awakeFromNib()    let view = UIView(frame: contentView.bounds)    view.isUserInteractionEnabled = false    view.autoresizingMask = [.flexibleWidth, .flexibleHeight]    view.backgroundColor = UIColor(white: 0.94, alpha: 1.0)    selectedBackgroundView = view}