滚动时应用 CollectionView layerMask “抖动”

Posted

技术标签:

【中文标题】滚动时应用 CollectionView layerMask “抖动”【英文标题】:CollectionView layerMask "jitter" when applied while scrolling 【发布时间】:2017-08-23 14:03:40 【问题描述】:

我正在开发一个视图控制器原型,该原型由具有以下要求的 collectionView 组成:

只有一张背景图片可见 部分可以像手风琴视图一样“折叠” 列表中的第一个视图(从现在起称为“主标题”)“固定”到屏幕顶部,因此底部的按钮在滚动时保持可见 部分标题“粘”在主标题下方,并在下一个部分标题停靠在顶部时相互推开。这就像 tableView 中节标题的默认行为。 主标题、节标题和单元格都有透明背景

我决定使用 UICollectionView 作为我的解决方案。我本可以尝试解决 UITableView,但我希望在部分折叠和展开期间对动画进行更多控制。它还允许我通过继承 UICollectionViewFlowLayout 来更精细地控制屏幕上视图的定位。

由于透明度要求存在问题。因为所有视图都有清晰的背景,所以当发生重叠时(由于主标题和部分标题的粘性),我们可以同时看到所有单元格,而理想情况下,这些单元格应该位于其部分标题“下方”。我的解决方案是找到重叠视图之间的帧差异,并使用图层蒙版“隐藏”重叠视图的一部分,如果背景不透明,通常会隐藏。

由于某种原因,在滚动时,看起来图层蒙版的框架没有与 scrollView 的 contentOffset 同时更新,从而导致轻微但明显的“延迟”。我尝试了以下方法来解决这个问题(所有这些方法都表现出相同的行为):

    使用 CADisplayLink 并每帧更新图层蒙版。为了确定视图框架何时相交,我尝试了 UIView.frame 和 UIView.layer.presentation().frame。 在我的 UICollectionViewFlowLayout 子类上使用 UICollectionViewLayoutAttributes 来计算图层蒙版框架,而不是视图本身。 构建自定义 UICollectionViewLayout 子类并使用其布局属性来计算图层蒙版帧(消除它是由于 UICollectionViewFlowLayout 子类引起的可能性)。

我有一些关于这种行为的理论。可能存在同步问题,因为 collectionView 从 contentOffset 更改时更新运行循环的单独通道中的视图位置,图层蒙版的帧更改是由于某些隐式动画,或者图层蒙版在放置时无法正确渲染 -点。包装在禁用动作的 CATransaction 中排除了隐式动画问题,我会在读取 layer.presentation() 以进行遮罩帧计算时使用 displayLink 来排除同步问题。

其他有趣的注意事项,使用 UITableView 时不会发生这种行为,这就是为什么我认为它可能与运行循环有关。

下面是我的 github 页面上一个示例项目的链接,说明了上面讨论的行为。此示例中的单元格默认设置了背景颜色以更好地说明问题(很难看到它们何时是透明的)。

https://github.com/irtemed88/ScrollJitterTest-ios

任何关于为什么会发生这种行为的帮助或指示将不胜感激!

【问题讨论】:

【参考方案1】:

想通了。该解决方案类似于我在测试期间尝试过的方法。

这个问题似乎与运行循环有关(或者至少在更新滚动视图的内容偏移量时)。我没有根据集合视图中的视图计算图层蒙版框架,而是使用自定义 UICollectionViewLayout 和每个项目的相应 UICollectionViewLayoutAttributes 来计算蒙版框架。布局属性似乎与屏幕上视图的重新定位同步更新。设置掩码时关闭这些值可以解决问题。

【讨论】:

以上是关于滚动时应用 CollectionView layerMask “抖动”的主要内容,如果未能解决你的问题,请参考以下文章

当collectionView滚动时,如何使iOS collectionView的特定单元格淡出?

滚动时collectionview更改单元格背景图像

Collectionview 图像单元格滚动问题

当用户点击 InputAccessoryView 时如何滚动到 CollectionView 的底部

使用一个collectionview IOS滚动多个UICollectionView

当scrollview快速滚动时如何滚动collectionView?