如何使用CAMediaTimingFunction模拟TableView的运动

4

我有一个表格视图和另一个视图,我想要动画另一个视图,使其在滚动时以与表格视图相同的动画曲线减速并停止。因此,我的想法是在实现表格视图滚动时,在代理方法中同时实现另一个视图的动画效果。

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset

并使用 velocity(每毫秒像素数)、targetContentOffset 和表视图的 decelerationRate 属性,使用物理公式 d=(vi+vf)/2*t 计算动画停止所需的时间。一旦我得到了这个时间,我只需要使动画以与表视图相同的速度减速,以使它们看起来“同步”。如何使用 CAMediaTimingFunction 和表视图的 decelerationRate 属性来实现这一点呢?
谢谢!
3个回答

0
我建议您插入scrollViewDidScroll:委托回调并使用其偏移量来重新定位其他视图。您甚至可以在scrollViewWillEndDragging:中设置一个标志以开始侦听scrollViewDidScroll:。这是我知道的唯一精确匹配运动的方法。
scrollViewDidScroll:的技巧是不要使用动画,而是直接设置框架或位置。委托被频繁调用,因此动画看起来会很糟糕。

0

尝试使用UIAnimation并将动画曲线设置为UIViewAnimationCurveEaseOut,使用

+(void)setAnimationCurve:(UIViewAnimationCurve)curve

使用time = velocity / acceleration计算动画持续时间。

另一种方法是使用[UIScrollViewDelegate scrollViewDidScroll:],因为我认为即使用户停止拖动,只要滚动视图仍在滚动,它仍将被调用。


我已经使用了[UIScrollViewDelegate scrollViewDidScroll:]方法,它运行良好。 - TomSwift
我将尝试使用缓和曲线。从我的经验来看,使用scrollViewDidScroll时,我最终得到的模拟视图会跳动而不是平滑的。 - Kyle Rosenbluth
我尝试了动画,但不幸的是持续时间有点偏差,曲线仍然看起来不对。似乎需要在每次调用scrollViewDidScroll时更新它,但我不知道如何消除跳跃感。 - Kyle Rosenbluth

0

仅使用decelerationRateCAMediaTimingFunction可能无法实现此目标。原因是UIScrollView(其中包括您的UITableView实例)不公开用于其减速的时间函数。此外,据我们所知,UIScrollView使用的时间函数可能无法仅从decelerationRate完全计算出来。它还可能考虑其他因素,例如速度、仍然可用空间的长度,甚至对您不可见的因素等。

除非您能找到某个已经反向工程了所有这些东西的人,否则我建议尝试找到一种方法,让原始的UIScrollView(即UITableViewController)驱动您的其他视图的动画,以及其自己的内容。

例如,您是否可以将其他视图简单地设置为一个UITableCellUITableView本身的子视图,以便继承其所有运动?如果您不剪切边界,那可能完全没问题。您甚至可以仅在减速期间执行此操作,如果在适当的委托方法之前和之后进行视图层次结构操作。

或者,您可以实现委托方法scrollViewDidScroll:,获取滚动视图的contentOffset,并使用它来计算其他视图的位置,然后手动设置其框架。这可能仅适用于用户驱动的滚动,而不是自动减速。此外,您可能需要深入了解NSRunLoop模式的细节,以确保在滚动事件期间应用的更改生效。

WWDC 2012年,会话“使用滚动视图增强用户体验”提供了一个示例,捕获UIScrollView的滚动动作并将其用于驱动OpenGL视图的动画。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接