2010-07-15 48 views
3

说我要到球滚动1000个像素动画的权利,在这个过程中指定计时功能 - 是这样的:CAAnimation在周期性动画进度间隔中调用方法?

UIView *ball = [[UIView alloc] initWithFrame:CGRectMake(0,0,30,30)]; 
CABasicAnimation* anim = 
     [CABasicAnimation animationWithKeyPath:@"transform.translation.x"]; 
anim.toValue = [NSNumber numberWithFloat:ball.frame.origin.x + 1000.0]; 
              // move 1000 pixels to the right 
anim.duration = 10.0; 
anim.timingFunction = [CAMediaTimingFunction functionWithControlPoints: 
         0.1 :0.0 :0.3 :1.0]; // accelerate fast, decelerate slowly 
[ball.layer addAnimation:anim forKey:@"myMoveRightAnim"]; 

我最终想是有一个方法,说-(void)animationProgressCallback:(float)progress,在动画期间,在动画的进度的规则间隔中,根据开始值和结束值之间的绝对“距离”,即忽略定时功能。

我会尝试用球滚动1000像素到右边上面的例子来解释(以Y轴绘制,在我们的例子中100%= 1000像素):

alt text

我想我的回调方法在球进展250个像素时被调用。由于计时功能的原因,前250个像素可能会在达到= 2秒,达到总距离的一半ti = 0.7秒后(快速加速启动),750px标记另一个ti = 1.1秒后,并且需要剩余的时间= 5.2秒才能达到100%(1000px)标记。

会是什么伟大的,但没有提供:

如果动画称为动画正在进行间隔委托方法所描述的,我不会要问这个问题... ;-)

想法如何解决这个问题:

一个解决方案,我能想到的是计算贝塞尔曲线的价值观,其映射到TI ķ值(我们知道总动画持续时间),当动画开始时,我们会手动按顺序执行animationProgresssCallback:选择器。显然,这是疯了(手工计算贝塞尔曲线??),更重要的是,不可靠(我们不能依赖动画线程和主线程同步 - 或者我们可以吗?)。

任何想法??

期待您的想法!

回答

1

想法如何解决这个问题:

一个解决方案,我能想到的是 计算贝塞尔曲线的价值观, 映射到狄值(我们知道 总动画持续时间),以及 动画开始时,我们 依次执行我们的 animationProgresssCallback:选择器 手动延迟。

显然,这是疯了(手工计算 bezier曲线?)和更多 重要的是,不可靠(我们不能依赖 在动画线程和主要 线程同步 - 或我们可以吗?)。

其实这是可靠的。 CoreAnimation是基于时间的,因此您可以在动画真正开始时使用委托来通知。 关于计算贝塞尔路径......以这种方式来看:如果你想在OpenGLES中实现一个曲面,你将不得不计算一个Cubic Bezier!,这可能会更糟糕。大声笑。你的情况只是一个维度,如果你知道数学,那并不难。

+0

感谢您指出我不必担心线程间同步。这鼓励我按照我的建议去做。到目前为止,它看起来不错! – 2010-07-19 13:22:22