在哪里突出显示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中取代 – 覆盖setSelected
和setHighlighted
都是正确的。 根据您的情况,您可以考虑将自定义视图分配给在select时自动交换的backgroundView
和selectedBackgroundView
。
// 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 } } }