iOS,退出后台时重新启动动画

时间:2011-05-18 09:24:07

标签: iphone objective-c ios ipad core-animation

当我的应用程序退出后台时,动画停止了。这是正常的。但我想从当前状态重新启动我的动画。如果没有我到处捕捉,我该怎么做呢。

[UIView animateWithDuration:60 delay:0 options:(UIViewAnimationOptionCurveLinear |UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat | UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionBeginFromCurrentState) animations:^{
    [bg setFrame:CGRectMake(0, 0, 1378, 1005)];
} completion:nil];

我尝试在动画前放置一个设置框架,但这只是让它快速移动。

[bg setFrame:CGRectMake(0, 0, 1378, 1005)];

任何想法?

8 个答案:

答案 0 :(得分:27)

您可以在班级中为UIApplicationWillEnterForegroundNotification添加观察者:

- (void)addNotifications { 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterForeground) name:UIApplicationWillEnterForegroundNotification object:nil]; 
}

- (void)applicationWillEnterForeground { 
    [self animate]; 
}

- (void)animate { 
    [bg setFrame:CGRectMake(0, 0, 0, 0)]; 
    [UIView animateWithDuration:60 delay:0 options:(UIViewAnimationOptionCurveLinear |UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat | UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionBeginFromCurrentState) animations:^{
        [bg setFrame:CGRectMake(0, 0, 1378, 1005)];
    } completion:nil];
}

设置动画的开始状态非常重要(不要忘记删除通知观察者)

答案 1 :(得分:25)

@ dany_23的答案可行。

但是我遇到了另一种方法,如果您不需要恢复动画但重新启动动画,而不重新激活应用程序时视图或图层对齐,则可以正常工作。

中的

- (void)applicationWillResignActive:(UIApplication *)application

在viewcontroller中调用一个实现以下代码的方法。

[view.layer removeAllAnimations];
 // this following CGRect is the point where your view originally started 
[bg setFrame:CGRectMake(0, 0, 1378, 1005)]; 

并在

- (void)applicationDidBecomeActive:(UIApplication *)application

你在viewcontroller中调用一个只启动动画的方法。

之类的东西
[UIView animateWithDuration:60 delay:0 options:(UIViewAnimationOptionCurveLinear |UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat | UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionBeginFromCurrentState) animations:^{
      [bg setFrame:CGRectMake(0, 0, 1378, 1005)];
} completion:nil];

希望这有所帮助,感谢所有回复的人。

答案 2 :(得分:4)

当您的应用进入后台时,您必须暂停动画,并在应用再次变为活动状态时恢复动画。您可以找到一些示例代码here,其中介绍了如何暂停和恢复动画。

答案 3 :(得分:2)

如果我正确地理解了这个问题,那么你就是想创建一个动画并将其停在中间。

在这种情况下,我建议您使用某种“状态”变量来存储动画的状态(例如,帧属性)。您可以在此代码中使用此变量将正在设置动画的对象放在正确的位置。这可以在animationDidStop函数(animationDidStop:finished:)中完成。为了实现此功能,您必须使用委派。它意味着将AppNameViewController(或整个应用程序的一些其他唯一对象)设置为动画的委托,并在其m文件中编写实现。这将允许您在动画结束时运行“位置设置”代码。

下一个任务是存储动画状态。在运行动画时,Core Animation框架会创建一堆中间层(表示层)。这些图层在动画期间显示,然后被删除。当动画完成执行时,对象就会进入最终状态。实际上你必须在创建所谓的“显式动画”时设置它(如果你不这样做,动画将会播放但是对象最后会跳回来)。这些表示层中的每一个都有一个集合或它自己的所有属性的副本,称为“可动画属性”。当其中一个动画属性设置为动画的关键点时,Core Animation会调用返回YES / NO的(BOOL)needsDisplayForKey。它告诉Core Animation是否需要更改指定的键才能重新显示该层。 “重新显示”意味着为表示层调用drawInContext方法。在这里,您可以获取当前显示的表示层的属性,并将它们放入“状态”变量。

动画以线程播放,以便设置我使用委托的“状态”变量。它需要子类CALayer(让我们说'AnimLayer)并在其中定义一个协议,只有一个存储“状态”的方法。该方法有一个参数即状态。然后我实现了在AnimLayer类中存储状态的协议方法,并将唯一对象设置为委托。因此,那些表示层(AnimLayer副本)不会自己存储状态。相反,作为参数传递给委托函数的“state”值由唯一对象存储在主线程中。

我做了类似的事,但我的任务有点不同。对不起,我不知道更简单的方法。希望这会有所帮助。

答案 4 :(得分:2)

@Grzegorz Krukowski's answer对我来说就像是一种魅力。我只是想补充一下,如果您不需要从动画的中断处继续播放动画,而是模拟它继续在后台运行,则可以省略以下几行:

let timeSincePause: CFTimeInterval = self.convertTime(CACurrentMediaTime(), from: nil) - pausedTime
self.beginTime = timeSincePause

resume()扩展名的CALayer函数开始,并将beginTime设置为0.0

此外,即使应用程序没有进入后台,您也可以手动调用willResignActivedidBecomeActive方法来获取要在ViewController消失后继续播放的动画的方法。

答案 5 :(得分:1)

这种方式会更好,只需在ApplicationDelegate上注册就会成为方法和观察者的状态。

- (void)pauseAnimate{
    CFTimeInterval pausedTime = [self.layer timeOffset];
    self.layer.speed = 1.0;
    self.layer.timeOffset = 0.0;
    self.layer.beginTime = 0.0;
    CFTimeInterval timeSincePause = [self.layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
    self.layer.beginTime = timeSincePause;
}

- (void)stopAnimate{
    CFTimeInterval pausedTime = [self.layer convertTime:CACurrentMediaTime() fromLayer:nil];
    self.layer.speed = 0.0;
    self.layer.timeOffset = pausedTime;
}

答案 6 :(得分:0)

从swift5发布起。

这也值得注意。在某些情况下,您需要重置animation属性以使新的动画保持不变。我可以通过动画转换来确认这一点。

只需打电话...

view.layer.removeAllAnimations()

不够用,新的动画将无法运行。我还必须跑...

view.transform = .identity

我怀疑您可能可以将其设置为任何新值或保存以前的状态并进行设置。

答案 7 :(得分:-1)

我不记得确切的细节,但我认为你可以通过查看视图的图层边界和位置属性来获取框架的当前动画位置。你可以将它们存储在应用程序暂停状态,并在应用程序再次处于前台时恢复它们。