我有一个以编程方式创建的UICollectionView。我希望集合视图的行为方式如下:
1. User touches cell
2. Cell background color changes
3. User releases touch
4. Cell background color changes
这应该是一个快速的颜色变化,恰好在执行与点击操作相关的选择器之前发生,其中包含集合视图的viewcontroller从堆栈中弹出。
我一直在看这个问题:UICollectionView cell change background while tap
其中有以下用于此目的的方法摘要:
// 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 Select and Deselect issue并尝试实现[UICollectionView selectItemAtIndexPath:animated:scrollPosition:]并在didSelectItemAtIndexPath中调用它,但这也不起作用。集合视图数据源和委托已设置。
答案 0 :(得分:49)
问题是您正在更改突出显示上的颜色,并在取消选择上更改颜色,而不是取消选择
你应该改变这个:
- (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方法
中答案 1 :(得分:31)
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中设置基本集合视图的帮助,请参阅here。
答案 2 :(得分:6)
编辑:在Swift 3中回答
a=${lines[0]}
b=${lines[1]}
c=${lines[2]}
答案 3 :(得分:4)
这是我的解决方案。而且我确定它确实有效。
我提供了三种方法来突出显示一个单元格(selectedBackgroundView,tint cell.contentView
并着色一个特殊区域)。
使用方法:
1.继承BaseCollectionViewCell
并不做任何事;
2.继承并设置specialHighlightedArea = UIView()
和contentView.addSubView(specialHighlightedArea)
,然后对其进行布局或添加约束以使用自动布局;
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)
}
}
答案 4 :(得分:0)
简单的二进制逻辑解决方案。适用于Swift 3和Swift 4:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt
indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath) as! CategoryCell
let lastCellColor = cell.backgroundColor
if cell.isSelected {cell.backgroundColor = .green} else {cell.backgroundColor = lastCellColor}
}
答案 5 :(得分:0)
将所有子视图添加到contentView
内,
使用backgroundView
中的selectedBackgroundView
和UICollectionViewCell
。不要设置contentView.backgroundColor
。
// Add this inside your cell configuration.
private func setupSelectionColor() {
let backgroundView = UIView()
backgroundView.backgroundColor = .white
self.backgroundView = backgroundView
let selectedBackgroundView = UIView()
selectedBackgroundView.backgroundColor = .orange
self.selectedBackgroundView = selectedBackgroundView
}
// Add the deselection inside didSelectCallback
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionView.deselectItem(at: indexPath, animated: true)
}