UIScrollView contentOffset在更改时不更新

时间:2018-04-11 10:30:17

标签: ios swift uiscrollview cadisplaylink

看到围绕更改滚动视图的内容偏移属性的奇怪问题。

我有CADisplayLink每帧调用一个方法。此方法计算调整内容偏移量的量,以产生自动滚动类型效果。

@objc private func tick() {

    let fps = 1 / (displayLink.targetTimestamp - displayLink.timestamp)

    let relativeAutoscrollAmount = autoscrollAmount / CGFloat(fps)

    scrollView.contentOffset.x += relativeAutoscrollAmount
}

autoscrollAmountCGFloat属性,表示每秒移动的像素数。在像iPhone一样的60Hz屏幕上,这意味着如果此属性为5,则每次调用该方法时会移动5/60。但是,内容偏移实际上永远不会改变!无论是在视觉上还是在记忆中,我都可以随时打破并检查它,它始终为0!

请注意,如果我每次调整1或更高,它就可以正常工作。不过,动画很快就会做到这一点。

有什么想法吗?

编辑:显然,你实际上不能一次调整少于一个像素,但是当我以前使用约束常量执行此操作时,系统只计算了如何处理这个问题。 (我假设只移动每几个滴答声。)

1 个答案:

答案 0 :(得分:0)

我相信我有答案,或者至少是基于一些非常好的证据支持的理论的解释。我们走了......

在这个问题中,我提供了一个5/60的例子,其中5是每秒移动的像素数量,60是我的屏幕刷新率。这大约是0.083,正如我所说,导致contentOffset没有更新。

此时,我认为最小值为1(因为您无法对半个像素进行更改),但事实并非如此。我开始尝试使用不同的十进制值,希望找到contentOffset更新停止发生的阈值。

经过大量的反复试验,我发现了这个价值。 0.167 。在我的脑海里,这绝对没有任何意义;但显然必须有一些东西,所以我开始以各种方式操纵它,试图观察某种模式。

很快就清楚0.167 * 6 == 1,虽然这是一个有趣的观察,但似乎没有什么意义。直到您注意到我测试的iPhone X上显示器的刷新率 60Hz 10次6 。在这一点上,我仍然在黑暗中盲目地刺伤,但这至少是一个我可以探索的领导。

据此,我推测系统每6ms评估一次层位置的变化,或者更实际地,每个显示周期10次。这支持了我所看到的行为,只要移动值过小(IE无法在每个显示周期中表示10次这种情况),它就会被忽略。

这是一个非常大胆的推测,所以我决定看看我是否可以收集证据来支持这一理论。我点了我的iPad pro,它有一个120Hz的显示器(而不是我的iPhone X上的60Hz显示器),看看是否有趋势。果然,有。现在看到移动的最小值是<60>屏幕上的一半。鉴于更高的刷新率(实际上是双倍),以及每个屏幕周期10次更新的原始假设,我现在看到每个屏幕周期有20次更新,每6ms ,和以前一样。这里肯定是一种关系。

现在我想强调这一切都是纯粹的猜测,但至少我今晚可以睡觉,知道为什么会发生这种情况!我也喜欢听别人的想法。