Question

I have a UIViewController that, depending on the frequency set by user, displays images in a animateWithDuration fade-in/fade-out every X seconds (say, 5 or 10). To manage the regularly timed calls to fade-in/out the images, I have a NSTimer that is set every time viewWillAppear is called.

Some function that does the animation, let's call it "showImageNow":

// on...
[UIView animateWithDuration:someInterval
                      delay:0
                    options:UIViewAnimationCurveEaseInOut
                 animations:
                    ^{
                        // UI alpha = ... code here
                    }
                 // off...
                 completion:^(BOOL finished){


                     [UIView animateWithDuration:someOtherInterval
                                           delay:yetAnotherValue
                                         options:UIViewAnimationCurveEaseInOut
                                      animations:
                                        ^{
                                            // UI alpha = ... code here
                                        }
                                      completion:nil
                      ];
                 }
 ];

In viewWillAppear:

if(myTimer != nil)
{
    [myTimer invalidate]; // in case user changed the frequency in settings view
}
myTimer = [NSTimer scheduledTimerWithTimeInterval: [[NSUserDefaults standardUserDefaults] doubleForKey:@"userFrequency"]
    target:self
    selector: @selector(showImageNow:)
    userInfo: nil
    repeats: YES];

In viewDidAppear:

if(myTimer) { [myTimer fire]; }

While everything works as expected most of the time, the fade-out part of the first animation is cut off/stutters every time the UIViewController is re-appeared (from say, app went to background or app was in another view). The fade-in part of the animation works always, oddly enough. This is observed on a real device, not the simulator. So the fade-in/out works for every animation except the first one (the fade-out part doesn't work).

Notes:

  • Yes, I've tried [myTimer fire] in the viewWillAppear (instead of viewDidAppear) as well, but this causes other issues like the UIViewController's elements show up rather abruptly when user switches to that view from other views or from background mode.
  • The frequency is much longer than the animateWithDuration's animation values, so there shouldn't be any frame overlaps or whatever UI overlaps there may be.
  • I put debug code before every animateWithDuration call in the UIVIewController, so I know for certain that no other animateWithDuration is interrupting the very first image animateWithDuration call.

So this is perplexing. I've tried using CADisplayLink but apparently that's not the right way to do it. Any ideas how to resolve this issue?

Was it helpful?

Solution

I'd try enabling the UIViewAnimationOptionBeginFromCurrentState option in your animation code and see if that helps

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top