【问题标题】:How to call scrollViewDidScroll: the same way UIScrollView does, but during custom animation?如何调用scrollViewDidScroll:与UIScrollView 一样,但在自定义动画期间?
【发布时间】:2012-04-29 21:23:58
【问题描述】:

我有一个非常大的水平滚动 UIScrollView,它正在重用其子视图(当它们超出可见区域时移动和更新它们,类似于 UITableView 正在重用单元格)。这依赖于 scrollViewDidScroll: 委托调用,它给了我实际的 contentOffset,在这里我决定何时重用特定的子视图。到目前为止一切顺利。

有时我需要以编程方式更改 contentOffset,但需要使用自定义动画(惯性和弹回最终位置)。使用核心动画我可以很容易地做到这一点。

问题是,在自定义动画期间,scrollViewDidScroll: 委托方法未被调用 -> 我必须手动执行,以便子视图重用工作。 我尝试通过每 0.02 秒触发一次的计时器来调用它。现在有两个问题:

  1. 我必须使用 [[_scrollView.layer presentationLayer] bounds].origin.x 获取 UIScrollView contentOffset,因为在动画期间正常 _scrollView.contentOffset 不会改变。

    但是,presentationLayer 提供的信息不足以进行精确同步 - 有时会有点晚。

  2. 问题是当新的 contentOffset 远离当前位置时。看起来内置的 UIScrollView 动画是 CAKeyframeAnimation,并且应该在关键帧位置上调用 scrollViewDidScroll。但我无法得到这些。

    如果我依赖与关键帧同步的计时器,视图会在错误的位置重复使用,我在动画期间根本看不到它们。

谁能解释一下 UIScrollView 在 setContentOffset:X animated:YES 期间究竟是如何以及何时调用 scrollViewDidScroll 的?是否可以在不违反应用商店规则的情况下重现它?

【问题讨论】:

    标签: ios cocoa-touch uiscrollview core-animation cakeyframeanimation


    【解决方案1】:

    首先,我不会使用延迟为 0.02 秒的NSTimer - 这不是计时器的用途。尝试使用CADisplayLink,它每帧触发一次。


    在您的回调方法中,如果您的自定义动画正在运行,您可以运行您自己的物理代码并分别调用 -setContentOffset:animated:。这甚至可以让您以指数方式缓解 CA 不允许您这样做。

    【讨论】:

    • 非常感谢,现在同步好多了。但是仍然存在一个问题:当滚动到长距离时,视图重用并没有赶上滚动的步伐。当通过触摸事件(用户正在滚动)非常快速地滚动时,也会发生同样的情况。一旦我停止使用表示层进行位置跟踪,用户滚动,即使是最快的轻弹也会恢复平滑。所以看起来询问表示层有点慢。有什么方法可以在滚动期间强制 UIScrollView 更新 contentOffset,就像默认行为一样?它可能会加快速度。
    • 对不起,应该告诉你:在你的CADisplayLink 的回调调用-setNeedsLayout 或你执行重用代码的任何方法中。
    • 是的,我在回调中调用了 scrollViewDidScroll:。明天我将尝试在仪器中进行分析,以找出性能问题所在。您正在 setNeedsLayout 中执行重用?
    • 是的。当您仍有问题时,您能否给我发电子邮件(请参阅我的个人资料),这样我们就不必在此处继续讨论 SO?
    • 解决方法是在 CADisplayLink 回调中调用 setContentOffset:X。偏移 X 是时间输入动画函数的结果。每个 setContentOffset 调用 scrollViewDidScroll: 委托方法与显示帧速率完美同步。这正是 UIScrollView 在幕后工作的方式。非常感谢 Jenox 为我指明了正确的方向。
    猜你喜欢
    • 2011-11-11
    • 1970-01-01
    • 1970-01-01
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-04
    • 2014-02-17
    相关资源
    最近更新 更多