6

我有一个非常大的水平滚动 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。但我无法得到这些。

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

任何人都可以阐明在 setContentOffset:X animated:YES 期间 UIScrollView 如何以及何时调用 scrollViewDidScroll?是否可以在不违反应用商店规则的情况下重现它?

4

1 回答 1

4

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


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

于 2012-04-18T13:01:57.167 回答