Search code examples
c#animationuiviewcontrollerxamarin.ioscore-animation

Best way to Pause/Resume dozens of animations?


Let's say my app is running dozens of animations simultaneously and I want to pause them all as if this were a game and the user hit the pause button. What's the best way to do that? I'm using a combination of CAKeyFrameAnimations, UIView.Animate(), CABasicAniamtions, etc. Obviously I could manually stop them all when the user hits pause, and resume them from where they stopped when the user un-pauses.. But is there a better way to do this?


Edit: I want to be able to Pause & Resume via user pressing a button.


2nd Edit: I got like 90% of the way there, but I'm still having a problem...

Here's my Xamarin iOS project: https://www.dropbox.com/s/5zbhhao6cijtb1i/Test_Pause.zip

Useful Apple reference: https://developer.apple.com/library/ios/qa/qa1673/_index.html

I have an app that starts an position animation. When I pause it the first time, it pauses correctly. When I hit resume, it resumes correctly from right where it was paused. But when you hit pause again a 2nd time (during the same animation) it resumes at a position as if it had never paused to begin with. It pauses way ahead of where it should be. The desired result of course is to have it halt exactly where it is when you hit the pause button.

Sorry if this sounds confusing, the example project i've attached is really simple, to reproduce the problem, download my app from the link above. Run it. Make sure to Pause, Resume, then Pause again all within the same animation. Any idea what I'm doing wrong?


Solution

  • I can now successfully pause and resume animations with CAMediaTiming, all without having to Stop the aniamtion and change the duration and start it again. See this useful resource

    Class Level Variables:

    UIView MyImage;
    double timeSincePause = 0;
    double pauseTime = 0;
    

    Pause Function:

    MyImage.Layer.Speed = 0.0f;
    MyImage.Layer.TimeOffset = MyImage.Layer.ConvertTimeFromLayer(CAAnimation.CurrentMediaTime(), MyImage.Layer) - timeSincePause;
    

    Resume Function:

    pauseTime = MyImage.Layer.TimeOffset;
    MyImage.Layer.Speed = 1.0f;
    MyImage.Layer.TimeOffset = 0.0f;
    MyImage.Layer.BeginTime = 0.0f;
    timeSincePause = (MyImage.Layer.ConvertTimeFromLayer(CAAnimation.CurrentMediaTime(), MyImage.Layer) - pauseTime);
    MyImage.Layer.BeginTime = timeSincePause;