在哪里突出显示UICollectionViewCell:代表或细胞?

根据“ 集合视图编程指南”,应该处理UICollectionViewDelegate单元格高亮的可视状态。 喜欢这个:

 - (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]; } 

我不喜欢这种方法是,它增加了对细胞非常特定的代表的逻辑。 事实上, UICollectionViewCell通过highlighted属性独立pipe理突出显示的状态。

不会压倒一切setHighlighted:是一个更清洁的解决scheme,然后呢?

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

这种方法有什么缺点,而不是委托方法?

正如文档所述,在单元格突出显示时,可以依靠highlighted属性进行更改。 例如,下面的代码会突出显示单元格(不是它的子视图):

 - (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); } } 

如果你添加这样的背景会变成紫色(红色+不透明的蓝色):

 - (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; } 

所以你可以一起使用(不一定都改变单元格的外观)。 不同的是,使用委托方法你也有indexPath 。 它可能用于创build多选(您将使用此方法与select委托方法),以显示一些预览,而单元格突出显示,以显示其他视图的一些animation…有这个委托相当多的设备方法在我看来。

作为结论,我将把单元格外观由单元本身来处理,并使用委托方法让控制器在同一时间做一些很酷的事情。

那么…所有这些方法都是正确的。 我已经find了对我来说最简单的方式。 只需重写setSelected:方法(例如更改背景颜色):

 -(void)setSelected:(BOOL)selected{ self.backgroundColor = selected?[UIColor greenColor]:[UIColor grayColor]; [super setSelected:selected]; } 

…它“开箱即用”(即使与collectionView.allowsMultipleSelection)

下面概述了两种可能的方法。

细胞亚类

如果已经从UICollectionViewCell则采用更UICollectionViewCell

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

UICollectionViewDelegate

不太干净,需要集合视图委托来了解单元的表示逻辑。

 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 } } 

请注意, UICollectionViewCell有一个selectedBackgroundView属性。 默认情况下,它是零。 只需为该属性创build一个视图,并在用户触摸该单元格时出现。

 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 } 

直接从UICollectionViewCell.h中取代 – 覆盖setSelectedsetHighlighted都是正确的。 根据您的情况,您可以考虑将自定义视图分配给在select时自动交换的backgroundViewselectedBackgroundView

 // Cells become highlighted when the user touches them. // The selected state is toggled when the user lifts up from a highlighted cell. // Override these methods to provide custom UI for a selected or highlighted state. // The collection view may call the setters inside an animation block. @property (nonatomic, getter=isSelected) BOOL selected; @property (nonatomic, getter=isHighlighted) BOOL highlighted; // The background view is a subview behind all other views. // If selectedBackgroundView is different than backgroundView, it will be placed above the background view and animated in on selection. @property (nonatomic, retain) UIView *backgroundView; @property (nonatomic, retain) UIView *selectedBackgroundView; 

Swift版本:(根据A-Live的回答)

 import UIKit class MyCollectionViewCell: UICollectionViewCell { override var highlighted: Bool { didSet { self.setNeedsDisplay() } } override func drawRect(rect: CGRect) { super.drawRect(rect) if self.highlighted { myImageView.highlighted = true //update an imageview } else { myImageView.highlighted = false //update an imageview } } }