【问题标题】:CAKeyframeAnimation over bezier curve stops (continually) when adBannerView is expanded当 adBannerView 展开时,贝塞尔曲线上的 CAKeyframeAnimation 停止(连续)
【发布时间】:2014-07-18 19:05:52
【问题描述】:

所以我刚刚在我的应用程序(一个基本的杂耍游戏)中实现了一个 adBannerView,当它展开时(即在委托上调用bannerViewActionShouldBegin),导致 CALayers 上的 CAKeyFrameAnimations(过度定义的贝塞尔曲线)不断停止并在其上调用 animationDidStop代表。持续,我的意思是大约每 0.001 秒一次。

我已经在我的游戏中实现了一个 pause 方法,当调用它时(通过绑定到 UIButton 的动作),将每个球对象的 CALayer 速度设置为 0.0,从而有效地将它们停止在动画中间。有一个布尔条件定义了游戏是否暂停,它决定了在调用方法时执行暂停代码的哪一部分。代码如下:

- (IBAction)pauseButton:(id)sender {
    if (isPaused == NO) {
        isPaused = YES;
        [_pauseButtonOutlet setImage:playButtonImage forState:UIControlStateNormal];
        [_pauseButtonOutlet setImage:playButtonImage forState:UIControlStateSelected];
        for (x = 0; x < [ballsArray count]; x++) {
            [[ballsArray objectAtIndex:x] setTimeOffset:[[ballsArray objectAtIndex:x] convertTime:CACurrentMediaTime() fromLayer:nil]];
            [[ballsArray objectAtIndex:x] setBeginTime:CACurrentMediaTime()];
            [[ballsArray objectAtIndex:x] setSpeed:0.0];
        }
        [_statusLabel setText:@"Paused"];

    } else if (isPaused == YES) {
        isPaused = NO;
        [_pauseButtonOutlet setImage:pauseButtonImage forState:UIControlStateNormal];
        [_pauseButtonOutlet setImage:pauseButtonImage forState:UIControlStateSelected];
        for (x = 0; x < [ballsArray count]; x++) {
            [[ballsArray objectAtIndex:x] setTimeOffset:[[ballsArray objectAtIndex:x] convertTime:CACurrentMediaTime() fromLayer:nil]];
            [[ballsArray objectAtIndex:x] setBeginTime:CACurrentMediaTime()];
            [[ballsArray objectAtIndex:x] setSpeed:1.0];
        }
        [_statusLabel setText:@""];

    }

}

此方法还可以作为(或者我认为)在扩展 adBannerView 的内容时暂停应用程序活动的便捷方式。但是,我发现当我返回界面时,我的 CALayer 球将处于动画的末尾(角色抓住它们的位置),但游戏仍然会暂停。取消暂停会使它们继续播放,就好像动画重新开始一样(当球落地时,动画停止,并在相反方向创建一个新动画)。

我认为在展示广告的过程中展示层可能发生了一些事情(因为在每个动画开始时,我将 CALayer 本身移动到结束点,但仍然在贝塞尔曲线上为展示层设置动画起点)。但是在我的 animationDidStop 方法中添加了一个快速的 NSLog 语句之后(我说“方法”是因为总共有四个球类,每个类都设计为在定义的路径上进行动画处理,并且每个都有自己的 animationDidStop 委托方法),我发现,对于一些奇怪的原因,所有实例化球的停止方法都被连续调用并且间隔非常接近(~.001s)。当广告关闭时,此活动停止(我使用 bannerViewActionDidFinish 再次调用暂停函数,自动恢复游戏)。

我希望有人能帮我解决这个问题。我制定了一个伪解决方案(从横幅暂停时获取球的位置,为 x 和 y 值创建 nsnumber 数组,并从它们停止的点取消暂停重新启动动画,贝塞尔曲线的控制点和主要点是动态计算的),但这使得动画不规则并且不符合标准的球动画。我真的很感激能够从它们停止的地方恢复动画,就像在常规暂停方法中一样。

感谢您阅读所有这些内容,非常感谢您提供任何帮助。此外,如果您需要/想查看我的其他代码,我很乐意提供帮助。

更新:在考虑了一些代码之后,我最好的猜测是横幅显示迫使动画过早停止,这导致它(球 CALayer)在其委托上调用 animationDidStop 方法。由于该方法会自动创建一个新动画,因此会创建一个无休止的循环 new-stop-new-stop-new-etc。这也可以解释为什么有时球会落在它应该落地的一侧,而有时它会落在预期的一侧。

据此,我了解到 adBannerView 在展开时会强制所有 CAAnimation 停止。如果我是对的,有什么办法可以解决吗?

【问题讨论】:

    标签: ios objective-c animation calayer adbannerview


    【解决方案1】:

    也许当你恢复层时,你可以检查是否有添加动画。如果没有,您可以添加具有正确 timeOffset 的新动画。

    另外,与使用快速枚举相比,您是否有任何理由不使用快速枚举 for (x = 0; x

    【讨论】:

    • 我正在考虑让它做类似的事情。我的问题:如何创建一个贝塞尔曲线动画,其中动画层已经是动画的一部分(假设这就是你所说的“时间偏移”)。至于我如何列举,嗯,我不知道。在进入 Objective C 之前,我使用 BASIC 和 C 进行了很多工作,我只是觉得用老式的方式做起来更舒服。哈哈。
    • 您可以添加相同的贝塞尔曲线动画。然后将动画timeOffset设置为暂停的timeOffset。这就是您在 obj c 中枚举的方式,对于 (CALayer *ball in ballsArray) { [ball setTimeOffset:[ball convertTime:CACurrentMediaTime() fromLayer:nil]]; }
    • 好的,所以在打开广告横幅 (bannerViewActionShouldBegin) 之前,我将 NSNumber 值添加到“offsetsArray”,其中包含在动画 CALayers 上调用方法“timeOffset”时返回的多个类型 double .当我关闭bannerView(bannerViewActionDidFinish)时,我为每个图层创建新的动画,并使用它们的原始贝塞尔曲线路径,并执行以下操作:将每个动画的开始时间设置为CACurrentMediaTime(),将速度设置为1.0,并设置timeOffset到之前记录的数字。但是,它仍然不起作用。你有什么具体的方法吗?
    • 当横幅完成并且您检查该图层没有动画时,首先您应该设置图层速度 = 1,timeOffset = 0,beginTime = 0。然后您只需将 timeOffset 设置为您的动画。动画应该从给定的 timeOffset 开始。我以前使用过这种技术。如果它有效,请尝试。 CAKeyFrameAnimations *positionAnim = ...; positionAnim.timeOffset = timeOffset;
    • 位置动画的时间偏移量表示从开始层动画到开始横幅的确切持续时间,例如可能是 3 秒。
    猜你喜欢
    • 1970-01-01
    • 2012-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-20
    • 2011-03-10
    • 1970-01-01
    • 2013-01-21
    相关资源
    最近更新 更多