Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
253 views
in Technique[技术] by (71.8m points)

ios - Where to highlight UICollectionViewCell: delegate or cell?

According to the Collection View Programming Guide one should handle the visual state of the cell highlights in the UICollectionViewDelegate. Like this:

- (void)collectionView:(PSUICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
    MYCollectionViewCell *cell = (MYCollectionViewCell*)[collectionView cellForItemAtIndexPath:indexPath];
    [cell highlight];
}

- (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
    MYCollectionViewCell *cell = (MYCollectionViewCell*)[collectionView cellForItemAtIndexPath:indexPath];
    [cell unhighlight];
}

What I don't like about this approach is that it adds logic to the delegate that is very specific to the cell. In fact, UICollectionViewCell manages its highlighted state independently, via the highlighted property.

Wouldn't overriding setHighlighted: be a cleaner solution, then?

- (void)setHighlighted:(BOOL)highlighted
{
    [super setHighlighted:highlighted];
    if (highlighted) {
        [self highlight];
    } else {
        [self unhighlight];
    }
}

Are there any disadvantages to this approach instead of the delegate approach?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...