【问题标题】:CADisplayLink stops updating when UIScrollView scrolled当 UIScrollView 滚动时,CADisplayLink 停止更新
【发布时间】:2010-03-26 15:20:09
【问题描述】:

标题是不言自明的,但我在 CADisplayLink 触发的循环中完成了一些动画。但是,一旦我滚动添加到视图层次结构中的 UIScrollView,动画就会立即停止,只有在滚动完全停止并停止时才会再次返回......

无论如何要取消这种行为?

【问题讨论】:

  • 有人应该编辑问题:该类是 CADisplayLink,而不是 UIDisplayLink。
  • 2016 - 看来 .commonModes 确实是典型现代 iOS 的解决方案。请参阅:stackoverflow.com/a/4878182/294884 令人难以置信的是,五年来一直没有质量保证

标签: iphone objective-c cocoa-touch core-animation


【解决方案1】:

您还可以通过使用NSRunLoopCommonModes 而不是NSDefaultRunLoopModes 来减轻此问题的影响:

[displayLink addToRunLoop:[NSRunLoop currentRunLoop]
                  forMode:NSRunLoopCommonModes];

【讨论】:

  • 这样可以防止UIScrollView在渲染过程中接收run-loop调用,最后随时停止滚动。
  • 现在这确实似乎有效。 Eonil 描述的问题似乎已被 Apple 解决。真是惨败,Apple。
  • 这张剧照为我解决了这个问题
【解决方案2】:

使用另一个运行循环在另一个线程上运行显示链接(使用-addToRunLoop:forMode:)。所以创建一个新线程,在该线程上创建一个运行循环,然后在该线程/运行循环上运行 CADisplayLink。

【讨论】:

  • 这只是减少 UIScrollView 停止,不能消除。
  • 对于 2016 年:如今这实际上是错误的。 stackoverflow.com/a/4878182/294884
【解决方案3】:

使用UITrackingRunLoopMode。它专为滚动内容而设计。

否则,只需在-scrollViewDidScroll 调用渲染和呈现例程。

UIScrollView broken and halts scrolling with OpenGL rendering (related CADisplayLink, NSRunLoop)

【讨论】:

  • 为了记录,在 2016 年,这在我们测试的所有设备上都不起作用。这似乎是一个解决方案:stackoverflow.com/a/4878182/294884
【解决方案4】:

您可以在这里找到更好(更复杂)的解决方案:

Animation in OpenGL ES view freezes when UIScrollView is dragged on iPhone

允许您使用“NSRunLoopCommonModes”并避免在握住手指而不滚动时出现 OpenGL 冻结。

这与 Doug 发现的有关(将 CADisplayLink 的帧间隔设置为 2 而不是 1 固定 UIScrollView)。

【讨论】:

    【解决方案5】:

    实际上CADisplayLink 支持多种RunloopMode。 试试这个:

        [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:UITrackingRunLoopMode];
        [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    

    【讨论】:

      【解决方案6】:

      NSRunLoopCommonModes 似乎破坏了 uiscrollview 的弹性和连续性。

      【讨论】:

        【解决方案7】:

        我发现如果我将帧间隔设置为 2 而不是 1(所以每秒 30 帧)一切正常。所以我正在做的是在弹出窗口出现时将其设置为 2,并在它关闭时将其重置为 1。

        【讨论】:

          【解决方案8】:

          我们通过将frameInterval 从 1 更改为 2 解决了同样的问题。这实际上将 OpenGL 场景的渲染速率减半,但它仍然可以充分满足您的需求。

          帧间隔 显示前必须经过的帧数 链接再次通知目标。

          @property(nonatomic) NSInteger frameInterval 讨论 默认 值为 1,这会导致您的应用程序在 显示器的刷新率。如果该值设置为更大的值 大于 1,显示链接会在一小部分通知您的应用程序 本机刷新率。例如,将间隔设置为 2 会导致 显示链接每隔一帧触发一次,提供一半的帧 率。

          将此值设置为小于 1 会导致未定义的行为,并且 一个程序员的错误。

          【讨论】:

          • 这到底是如何解决错误的?问题似乎是动画停止了。将帧速率减半如何使其再次运行?这似乎是 0/2=0 的情况。
          • @OldPeculier 因为显示链接将每隔一帧触发一次,我们可以为其他系统任务腾出 CPU 时间,例如渲染滚动视图。试试看。
          • 您是说 CADisplayLink 没有触发它的回调是因为 CPU 过载,并且通过将回调的数量减半可以减轻 CPU 负载,从而执行回调。我觉得……令人惊讶。
          猜你喜欢
          • 1970-01-01
          • 2011-07-19
          • 1970-01-01
          • 2011-12-29
          • 2011-05-07
          • 2015-12-26
          • 1970-01-01
          • 2012-04-09
          相关资源
          最近更新 更多