简体   繁体   English

UIScrollView contentOffset更改后不更新

[英]UIScrollView contentOffset not updating when changed

Seeing an odd issue surrounding changing a scroll view's content offset property. 看到围绕更改滚动视图的content offset属性的奇怪问题。

I have a CADisplayLink that calls a method every frame. 我有一个CADisplayLink ,它每帧都调用一个方法。 This method calculates how much to adjust the content offset by to produce an auto scroll type effect. 此方法计算调整内容偏移量以产生自动滚动类型效果的程度。

@objc private func tick() {

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

    let relativeAutoscrollAmount = autoscrollAmount / CGFloat(fps)

    scrollView.contentOffset.x += relativeAutoscrollAmount
}

autoscrollAmount is a CGFloat property that represents how many pixels to move each second. autoscrollAmountCGFloat属性,表示每秒移动多少像素。 On a 60Hz screen like an iPhone, this would mean a shift of 5/60 per invocation of that method, if this property is 5. However, the content offset never actually changes! 在iPhone等60Hz的屏幕上,如果此属性为5,则表示该方法每次调用移动5/60。但是,内容偏移量实际上从未改变! Either visually or in memory, I can break and inspect it at any time and it's always 0! 无论是视觉上还是内存中,我都可以随时对其进行检查并检查,并且始终为0!

Note that if I adjust it by 1 or greater each time, it works just fine. 请注意,如果我每次将其调整为1或更大,它就可以正常工作。 The animation is far to quick doing this, though. 不过,动画远不能很快做到这一点。

Any thoughts? 有什么想法吗?

EDIT: Obviously you can't actually adjust by less than a pixel at a time, but when I was doing this previously with a constraint constant, the system just calculated how to deal with this. 编辑:显然您一次不能实际调整小于一个像素,但是当我之前使用约束常量进行此调整时,系统只是计算了如何处理。 (I assume by only moving every few ticks). (我假设只每移动几个刻度线一次)。

I believe I have the answer, or at the very least, an explanation based on a theory backed by some pretty good evidence. 我相信我有答案,或者至少是有一些很好的证据支持的基于理论的解释。 Here we go... 开始了...

In the question, I provided an example of 5/60, where 5 is the amount of pixels to move per second, and 60 is the refresh rate of my screen. 在问题中,我提供了一个5/60的示例,其中5是每秒移动的像素量,而60是屏幕的刷新率。 This comes out at approximately 0.083, which, as I said, caused no updates to contentOffset to take place. 大约是0.083,正如我所说,这不会导致contentOffset发生更新。

At this point, I assumed that the minimum value was 1 (as you can't make changes to half a pixel) but this is in fact not the case. 在这一点上,我假设最小值为1(因为您无法将像素更改为半像素),但实际上并非如此。 I began experimenting with different decimal values, in the hope of finding the threshold at which the updates to contentOffset stop taking place. 我开始尝试使用不同的十进制值,以期找到停止对contentOffset进行更新的阈值。

After a lot of trial and error, I found that value. 经过大量的反复试验,我发现了这一价值。 It is 0.167 . 0.167 In my head, this had absolutely no significance whatsoever; 在我看来,这绝对没有任何意义。 but there obviously had to be something so I set about manipulating it in various ways to try to observe a pattern of some kind. 但是显然必须有一些东西,因此我着手以各种方式对其进行操作以尝试观察某种模式。

It soon became clear that 0.167 * 6 == 1 , which although an interesting observation, again seemed to have little significance. 很快就知道0.167 * 6 == 1 ,尽管这是一个有趣的观察,但似乎又没有什么意义。 That is until you note that the refresh rate of the display on my iPhone X that I was testing with is 60Hz , 10 times 6 . 直到您注意到我正在测试的iPhone X上的显示屏刷新率为60Hz ,是6的10倍 At this point, I'm still stabbing blindly in the dark but this was at least a lead that I could explore a bit. 此时,我仍然在黑暗中盲目刺伤,但这至少是我可以探索的线索。

From this, I speculated that the system evaluates changes in layer's positions either every 6ms, or, perhaps more realistically, 10 times per display cycle. 据此,我推测系统每6ms评估一次图层位置的变化,或者更实际地,每个显示周期评估10次。 This supports the behaviour I am seeing in so far as if the movement value passes is too small (IE it cannot be represented in this 10 times per display cycle theorm), it is simply ignored. 这支持我所看到的行为,即使移动值传递的值太小(即每个显示周期定理在这10次中都无法表示),则可以将其忽略。

This is quite a bold speculation so I decided to see if I could gather evidence to support the theory. 这是一个很大胆的推测,因此我决定看看是否可以收集证据来支持该理论。 I fired up my iPad pro which has a 120Hz display (as opposed to the 60Hz display on my iPhone X) to see if there was a trend. 我启动了具有120Hz显示屏(而不是iPhone X上的60Hz显示屏)的iPad Pro,以查看是否存在趋势。 Sure enough, there was. 果然有。 The minimum value to see movement was now half what it was on the 60Hz screen . 现在,看到运动的最小值是60Hz屏幕上的一半 Given the greater refresh rate (double, in fact), and the original assumption of 10 updates per screen cycle, I am now seeing 20 updates per screen cycle, every 6ms , as before. 鉴于更高的刷新率(实际上是两倍),以及最初的假设是每个屏幕周期10次更新,我现在看到与以前一样, 每个屏幕周期每6ms更新20次。 There's definitely a relationship here. 这里肯定有关系。

Now I'd like to stress that this is all purely speculation, but at least I can sleep tonight having a good idea as to why this is happening! 现在,我想强调的是,这纯粹是猜测,但至少我今晚可以睡个好觉,以了解发生这种情况的原因! I'd love to hear other's thoughts, too. 我也很想听听别人的想法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM