在didHighlightItemAt上更改UICollectionViewCell中的背景并且在滚动时didUnhighlightItemAt闪烁

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在didHighlightItemAt上更改UICollectionViewCell中的背景并且在滚动时didUnhighlightItemAt闪烁相关的知识,希望对你有一定的参考价值。

我想在UICollectionView中更改单元格的背景,同时用户点击或关注它。我想在用户点击之后给出不断变化的背景反馈,所以我在UICollectionViewDelegateFlowLayout中实现了这两个方法:

func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath) {
    if let cell = collectionView.cellForItem(at: indexPath) as? CustomCell {
        cell.highlight()
    }
}

func collectionView(_ collectionView: UICollectionView, didUnhighlightItemAt indexPath: IndexPath) {
    if let cell = collectionView.cellForItem(at: indexPath) as? CustomCell {
        cell.unhighlight()
    }
}

它很有用,但不幸的是当用户在集合上滚动时,会调用didHighlightItemAt方法并立即调用didUnhighlightItemAt方法,因此会导致单元格闪烁。

我想知道调度cell.highlight 0.1秒,如果didUnhighlightItemAt早于0.1调用,我会取消高亮调用。

但有更好的解决方案吗?

类似的效果发生在设置应用程序中(但它更难做到这一点,在我的应用程序中,它更容易看到闪烁的单元格):

Demo

答案
- (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
    cell.backgroundColor = UIColor.redColor;
}

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

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
    cell.backgroundColor = UIColor.orangeColor;
    return cell;
}

输出:

enter image description here

另一答案

你所描述的是预期的行为。如果您想避免这种情况,请使用cell.highlight(),但也要在单元格中添加一个计时器,以防止它突出显示。

您可以将这些方法添加到您的单元格中以实现此目的。如果用户在两秒钟后释放水龙头,这将允许小区自然不突出(如ios所示),否则它将在返回之前保持突出显示两秒钟。

override func prepareForReuse() {
    super.prepareForReuse()

    highlightTimer?.invalidate()
    unhighlight()
}

private var highlightTimer: Timer?
private var highlightDate: Date?
func highlight() {
    // Style your cell...

    highlightDate = Date()
    highlightTimer = Timer(timeInterval: 2.5, target: self, selector: #selector(unhighlight), userInfo: nil, repeats: false)
    highlightTimer?.fire()
}

@objc
func unhighlight() {
    if let highlightDate = highlightDate, abs(highlightDate.timeIntervalSinceNow) > 2.0 {
        // Un-style your cell...
    }
}

另一个解决方案是动画unhighlight的变化,以便在滚动时不那么刺耳。你可以通过在UIView.animate块中的unhighlight方法中包装你正在做的任何事情来做到这一点

另一答案

实现以下两个方法func collectionView(_ collectionView:UICollectionView,didSelectItemAt indexPath:IndexPath){

            let cell = collectionView.cellForItem(at: indexPath) as! TableCollectionViewCell
            cell.contentView.backgroundColor = UIColor.lightGray
    }



    func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
            let cell = collectionView.cellForItem(at: indexPath) as! TableCollectionViewCell
            cell.contentView.backgroundColor = UIColor.white
    }

它会解决你的问题。

以上是关于在didHighlightItemAt上更改UICollectionViewCell中的背景并且在滚动时didUnhighlightItemAt闪烁的主要内容,如果未能解决你的问题,请参考以下文章

使用 pyuic 与 uic.loadUi 的好处

如何使用 setupUi 或 uic 输出来创建没有父小部件的独立布局?

pyside-uic/pyuic4:找不到命令

pyside-uic 在哪里?

如何在运行时更改 CurrentCulture?

从 uic 输出到 Qt 中的 C++ 代码