根据Collection View Programming Guide,应该处理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
属性独立管理其突出显示的状态。
那么不会覆盖setHighlighted:
更清洁的解决方案吗?
- (void)setHighlighted:(BOOL)highlighted
{
[super setHighlighted:highlighted];
if (highlighted) {
[self highlight];
} else {
[self unhighlight];
}
}
这种方法有没有缺点而不是委托方法?
答案 0 :(得分:51)
正如文档所述,您可以在突出显示单元格时依赖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
。它可能用于创建多选(您将使用此方法与选择委托方法一起),在单元格突出显示时显示一些预览,以显示其他视图的一些动画...这个委托有相当多的设备我认为的方法。
作为一个结论,我会让单元格外观由单元格本身处理,并使用委托方法让控制器在同一时间内制作一些很酷的东西。
答案 1 :(得分:13)
下面概述了两种可能的方法。
单元格子类化
清除方法,如果已经从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
}
}
答案 2 :(得分:6)
嗯......因为所有这些方法都是正确的。我找到了对我来说最简单的方式。只需覆盖setSelected:方法(例如更改背景颜色):
-(void)setSelected:(BOOL)selected{
self.backgroundColor = selected?[UIColor greenColor]:[UIColor grayColor];
[super setSelected:selected];
}
......它的工作原理&#34;开箱即用&#34; (即使使用collectionView.allowsMultipleSelection)
答案 3 :(得分:6)
请注意,UICollectionViewCell
具有selectedBackgroundView
属性。默认情况下,它是零。只需为此属性创建一个视图,它将在用户触摸单元格时显示。
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
}
答案 4 :(得分:4)
足以突出显示单元格(Swift 4)
class MyCollectionViewCell: UICollectionViewCell {
...
override var isHighlighted: Bool {
didSet {
if isHighlighted {
self.contentView.alpha = 0.6
}
else {
self.contentView.alpha = 1.0
}
}
}
}
答案 5 :(得分:2)
直接从UICollectionViewCell.h获取 - 覆盖setSelected
和setHighlighted
都是正确的。根据您的具体情况,您可以考虑将自定义视图分配给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;
答案 6 :(得分:0)
import UIKit
class MyCollectionViewCell: UICollectionViewCell {
override var highlighted: Bool {
didSet {
self.setNeedsDisplay()
}
}
override func drawRect(rect: CGRect) {
super.drawRect(rect)
myImageView.highlighted = self.highlighted
}
}
Swift 4
import UIKit
class MyCollectionViewCell: UICollectionViewCell {
override var isHighlighted: Bool {
didSet {
self.setNeedsDisplay()
}
}
override func draw(_ rect: CGRect) {
super.draw(rect)
myImageView.isHighlighted = self.isHighlighted
}
}