【问题标题】:Collection view header flickers when resizing at some values以某些值调整大小时,集合视图标题闪烁
【发布时间】:2018-04-24 03:16:57
【问题描述】:

我有一个自定义 UICollectionView 布局,可以在用户滚动时调整大小。随着标头在某一点收缩,它开始闪烁。

我猜问题是,当标题缩小时,集合视图认为它超出框架并可能将其出列,但随后它计算出它在框架中并重新排队,这可能是导致闪烁的原因。

class CustomLayout: UICollectionViewFlowLayout, UICollectionViewDelegateFlowLayout {

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {

    let layoutAttributes = super.layoutAttributesForElements(in: rect) as! [UICollectionViewLayoutAttributes]

    let offset = collectionView!.contentOffset ?? CGPoint.zero

    let minY = -sectionInset.top

    if (offset.y >= minY) {

        let setOffset = fabs(170 - minY)
        let extraOffset = fabs(offset.y - minY)

        if  offset.y <= 170 {

            for attributes in  layoutAttributes {
                if let elementKind = attributes.representedElementKind {
                    if elementKind == UICollectionElementKindSectionHeader {

                        var frame = attributes.frame

                        frame.size.height = max(minY, headerReferenceSize.height - (extraOffset * 1.25))
                        frame.origin.y = frame.origin.y + (extraOffset * 1.25)

                        attributes.frame = frame
                    }
                }
            }

        } else {

            for attributes in  layoutAttributes {
                if let elementKind = attributes.representedElementKind {
                    if elementKind == UICollectionElementKindSectionHeader {

                        var frame = attributes.frame

                        frame.size.height = max(minY, headerReferenceSize.height - (setOffset * 1.25))
                        frame.origin.y = frame.origin.y + (setOffset * 1.25)

                        attributes.frame = frame
                    }
                }
            }
        }
    }
    return layoutAttributes
}

override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
    return true
}
}

这是一个显示行为的 gif。请注意它是如何开始正常并开始闪烁的。快速滚动也会产生不良影响。

有什么建议吗?

【问题讨论】:

  • 你能录制一段视频来展示发生了什么吗?
  • @MaximoLucosi 感谢您的回复。我已经包含了一个描述行为的 gif。
  • 这看起来是个好问题。能否提供一些github链接等供我们测试?
  • 这种情况发生在模拟器和设备上吗?如果此工件当前仅在模拟器中观察到,模拟器是“实际大小”还是按比例缩小?我观察到模拟器在缩小时呈现异常,例如细线在超过亚像素阈值时闪烁可见/不可见。
  • 有趣的问题

标签: ios swift uicollectionview


【解决方案1】:

我认为您的问题与布局代码无关。我复制并尝试在一个简单的示例应用中使用您的 CustomLayout,没有明显的闪烁问题。

其他尝试:

  1. 确保您的collectionView(viewForSupplementaryElementOfKind:at:) 函数正确重用标题视图,使用collectionView.dequeueReusableSupplementaryView(ofKind:withReuseIdentifier:for:))。每次创建一个新的标题视图可能会导致大量延迟。
  2. 单元格本身是否有任何复杂的绘图代码?
  3. 在最坏的情况下,您可以尝试使用 Instruments Time Profiler 对应用进行分析,以查看哪些操作占用的 CPU 周期最多(假设丢帧是您的问题)。

【讨论】:

    【解决方案2】:

    看起来您的集合视图将标题移到了后面。

    尝试在更改标题框架的代码中插入此代码:

    collectionView.bringSubview(toFront: elementKind)
    

    【讨论】:

    • 谢谢!这就是我搜索的方式!
    • 在 layoutAttributesForElements 中? elementKind 是字符串类型,即使我做类似的事情(手动设置 zIndex),行为仍然存在。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-28
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多