Search code examples
iosmultithreadinguiscrollviewobjective-c-blocksblock

UIScrollView animation problems


I'm using a horizontal UIScrollView that displays photos on the first half of the screen. (Imagine a CGRect (0,0,320,120). The first scrollView is embedded in a second scrollview, which takes all the screen. When I scroll down the page (thus the second scrollView), the first scrollview stop being animated. I programmed a NSTimer to change photo every 3 seconds in the first UIScrollView, but while I'm scrolling the second scrollView, it seems like the animations are being queued. When I release my finger of the screen, there are few photo transitions (i.e: 2 changes if I scrolled without stoping for 6 seconds). In short: how can I make use of blocks (or something else) to continue my animations while I'm scrolling the second scrollView?

My NSTimer (in viewDidLoad):

timer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(changePage:) userInfo:nil repeats:YES];

Solution

  • Your iOS app has a run loop that continually checks for things like user input. If it is busy detecting touch events, things that are scheduled on that run loop will not get performed. (Similarly, if you block the main thread with e.g. a big server request, you won't get touch events during that time).

    Here's how you can get the NSTimer on the right run loop:

    First, use timerWithTimeInterval:target:selector:userInfo:repeats: to create a timer not scheduled on a run loop. Second, use - (void)addTimer:(NSTimer *)aTimer forMode:(NSString *)mode to schedule the timer on a run loop. For the mode argument (the run loop type), use NSRunLoopCommonModes to allow the timer to fire without having to wait on the main run loop.

    Note that this same effect exists for e.g. performSelectorAfterDelay if done in the main run loop. It also applies to animation completion blocks. I'm not sure if there's an easy way around the animation completion block problem besides using CoreAnimation.