Hey I had stumbled upon the same thing in my game, and ended up finding a somewhat different solution than you, which you may like 🙂 I figured I should share the workaround I found…
My case is using UIView/UIImageView animations, but it’s basically still CAAnimations at its core… The gist of my method is that I copy/store the current animation on a view, and then let Apple’s pause/resume work still, but before resuming I add my animation back on. So let me present this simple example:
Let’s say I have a UIView called movingView. The UIView’s center is animated via the standard [UIView animateWithDuration…] call. Using the mentioned QA1673 code, it works great pausing/resuming (when not exiting the app)… but regardless, I soon realized that on exit, whether I pause or not, the animation was completely removed… and here I was in your position.
So with this example, here’s what I did:
- Have a variable in your header file called something like animationViewPosition, of type *CAAnimation**.
-
When the app exits to background, I do this:
animationViewPosition = [[movingView.layer animationForKey:@"position"] copy]; // I know position is the key in this case... [self pauseLayer:movingView.layer]; // this is the Apple method from QA1673
- Note: Those 2 ^ calls are in a method that is the handler for the UIApplicationDidEnterBackgroundNotification (similar to you)
- Note 2: If you don’t know what the key is (of your animation), you can loop through the view’s layer’s ‘animationKeys‘ property and log those out (mid animation presumably).
-
Now in my UIApplicationWillEnterForegroundNotification handler:
if (animationViewPosition != nil) { [movingView.layer addAnimation:animationViewPosition forKey:@"position"]; // re-add the core animation to the view [animationViewPosition release]; // since we 'copied' earlier animationViewPosition = nil; } [self resumeLayer:movingView.layer]; // Apple's method, which will resume the animation at the position it was at when the app exited
And that’s pretty much it! It has worked for me so far 🙂
You can easily extend it for more animations or views by just repeating those steps for each animation. It even works for pausing/resuming UIImageView animations, ie the standard [imageView startAnimating]. The layer animation key for that (by the way) is “contents”.
Listing 1 Pause and Resume animations.
-(void)pauseLayer:(CALayer*)layer
{
CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
layer.speed = 0.0;
layer.timeOffset = pausedTime;
}
-(void)resumeLayer:(CALayer*)layer
{
CFTimeInterval pausedTime = [layer timeOffset];
layer.speed = 1.0;
layer.timeOffset = 0.0;
layer.beginTime = 0.0;
CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
layer.beginTime = timeSincePause;
}