更改UICollectionView单元格的背景

我有一个以编程方式创建的UICollectionView。 我希望集合视图以下列方式运行:

1. User touches cell 2. Cell background color changes 3. User releases touch 4. Cell background color changes 

这应该是一个快速的颜色更改,它发生在与执行tap操作相关的选择器之前,其中包含集合视图的viewcontroller从堆栈中弹出。

我一直在看这个问题: UICollectionView单元格改变背景,同时点击

其中有以下用于此目的的方法摘要:

 // Methods for notification of selection/deselection and highlight/unhighlight events. // The sequence of calls leading to selection from a user touch is: // // (when the touch begins) // 1. -collectionView:shouldHighlightItemAtIndexPath: // 2. -collectionView:didHighlightItemAtIndexPath: // // (when the touch lifts) // 3. -collectionView:shouldSelectItemAtIndexPath: or - collectionView:shouldDeselectItemAtIndexPath: // 4. -collectionView:didSelectItemAtIndexPath: or -collectionView:didDeselectItemAtIndexPath: // 5. -collectionView:didUnhighlightItemAtIndexPath: 

我假设我只需要从“触摸开始时”和“触摸结束时”实现上述方法之一。 但无论我做什么,看起来背景颜色会发生变化然后仍然会发生变化。 这是我尝试过的一些不起作用的例子:

 - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { //pop vc } - (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath]; cell.contentView.backgroundColor = [UIColor redColor]; } - (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath]; cell.contentView.backgroundColor = [UIColor greenColor]; } 

这导致单元格背景颜色仅变为红色。 我还看了这个问题: UICollectionView选择并取消选择问题并尝试实现[UICollectionView selectItemAtIndexPath:animated:scrollPosition:]并在didSelectItemAtIndexPath中调用它,但这也不起作用。 设置了集合视图数据源和委托。

问题是您正在更改突出显示的颜色并在取消选择时将其更改为取消选择而不是取消选择

你应该改变这个:

 - (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath]; cell.contentView.backgroundColor = [UIColor greenColor]; } 

对此:

 - (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath]; cell.contentView.backgroundColor = [UIColor greenColor]; } 

此外,如果您不想在发生突出显示之前稍等一下,则应将集合视图的delaysContentTouches属性设置为NO

编辑:还确保你打电话

 [collectionView deselectItemAtIndexPath:indexPath animated:NO]; 

在-didSelectItemAtIndexPath方法中

Swift 3版本

将以下两种方法添加到视图控制器类:

 // change background color when user touches cell func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath) { let cell = collectionView.cellForItem(at: indexPath) cell?.backgroundColor = UIColor.red } // change background color back when user releases touch func collectionView(_ collectionView: UICollectionView, didUnhighlightItemAt indexPath: IndexPath) { let cell = collectionView.cellForItem(at: indexPath) cell?.backgroundColor = UIColor.green } 

请参阅此处以获取有关在Swift中设置基本集合视图的帮助。

这是我的解决方案。 我相信它确实有效。
我提供了三种方法来突出显示一个单元格(selectedBackgroundView,tint cell.contentView和tint一个特殊区域)。

如何使用:
1.只是inheritanceBaseCollectionViewCell并且什么都不做;
2.inheritance并设置specialHighlightedArea = UIView()contentView.addSubView(specialHighlightedArea) ,然后布局或添加约束以使用Auto Layout;
3.如果你不需要高亮效果,只需编写一个名为’shouldHighlightItemAtIndexPath’的方法,由UICollectionViewDelegate定义并使其返回false,或设置cell.shouldTintBackgroundWhenSelected = false并设置specialHighlightedArea = nil并将其从superView中删除。

 /// same with UITableViewCell's selected backgroundColor private let highlightedColor = UIColor(rgb: 0xD8D8D8) /// you can make all your collectionViewCell inherit BaseCollectionViewCell class BaseCollectionViewCell: UICollectionViewCell { /// change it as you wish when or after initializing var shouldTintBackgroundWhenSelected = true /// you can give a special view when selected var specialHighlightedArea: UIView? // make lightgray background display immediately(使灰背景立即出现) override var isHighlighted: Bool { willSet { onSelected(newValue) } } // keep lightGray background until unselected (保留灰背景) override var isSelected: Bool { willSet { onSelected(newValue) } } func onSelected(_ newValue: Bool) { guard selectedBackgroundView == nil else { return } if shouldTintBackgroundWhenSelected { contentView.backgroundColor = newValue ? highlightedColor : UIColor.clear } if let area = specialHighlightedArea { area.backgroundColor = newValue ? UIColor.black.withAlphaComponent(0.4) : UIColor.clear } } } extension UIColor { convenience init(rgb: Int, alpha: CGFloat = 1.0) { self.init(red: CGFloat((rgb & 0xFF0000) >> 16) / 255.0, green: CGFloat((rgb & 0xFF00) >> 8) / 255.0, blue: CGFloat(rgb & 0xFF) / 255.0, alpha: alpha) } } 

编辑:在Swift 3中回答

 var selectedIndex = Int () func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell if selectedIndex == indexPath.row { cell.backgroundColor = UIColor.green } else { cell.backgroundColor = UIColor.red } return cell } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { selectedIndex = indexPath.row self.yourCollctionView.reloadData() } 
Interesting Posts