如何停止具有负时间偏移的CAKeyframeAnimation在路径结束时

5

我的应用程序中有一个屏幕,用户可以看到沿着弧线飞行的云。这个动画是通过使用CAKeyframeAnimation实现的,并且能够正确地运行。但是我想改进动画,使得当用户打开屏幕时,云必须看起来已经在动画中了。也就是说,云应该出现在弧线的中间位置。我是这样实现的:

theKeyframeAnimation.timeOffset = randomTimeOffset;

动画从给定的时间开始(偏移量为负)。但是!当云到达路径的结尾时,动画不会停止。云将继续从路径的起点移动!似乎动画持续时间没有改变。

我试图通过在特定时间后删除动画来修复此问题:

NSTimeInterval removingDelay = theKeyframeAnimation.duration + theKeyframeAnimation.offset;
dispatch_time_t dispatchTime = dispatch_time(DISPATCH_TIME_NOW,
                                             (int64_t)(removingDelay * NSEC_PER_SEC));
dispatch_after(dispatchTime, dispatch_get_main_queue(), ^
               {
                   [cloud.layer removeAnimationForKey:@"animation_along_arc"];
               });

但是这种解决方案效果不佳。动画时间和分派时间不同步。实际上,动画比所需的晚约0.5秒被移除。
更新: 现在我看到可能的解决方案。我可以用CAAnimationGroup包装每个动画。然后设置动画组的持续时间:
animationGroup.animations = @[theKeyframeAnima];
animationGroup.duration = theKeyframeAnima.duration + theKeyframeAnima.timeOffset;

我找到的是最优雅的解决方案。欢迎任何建议。

更新2:这个最后的解决方案也不起作用。可能我应该剪辑密码而不是改变时间偏移...


你尝试过设置动画的代理并实现animationDidStop:finished:方法吗?在这里有文档 - Trenskow
当然,我会使用这种方法,在前一个动画结束时使用随机参数创建新的动画。 - kelin
你如何实现曲率?也许你应该制作一个没有时间偏移的动画,然后调整你的曲线? - Trenskow
我使用CGPathAddArcToPoint()函数创建包含一条弧线的路径。 - kelin
1个回答

4
我找到了解决方法!问题不在CAKeyframeAnimation中,而在CAMediaTiming中。 在这个博客中解释了timeOffset实际上改变的是动画循环,而不是时间。
为了实现我的目的,我应该使用beginTime属性:
 NSTimeInterval currentTime = [targetLayer convertTime:CACurrentMediaTime()
                                             fromLayer:nil];
 anim.beginTime = currentTime + timeOffset;
 anim.duration = duration + timeOffset;

你应该关闭这个问题。 - johndpope
我认为当其中一个答案被标记为正确时,问题被视为已关闭。我错了吗? - kelin

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