Search code examples
iphoneobjective-cnstimer

NSTimer not working while dragging a UITableView


I have an application with a countdown timer. I've made it with a label that is updated with a function called from a timer this way:

...
int timeCount = 300; // Time in seconds
...
NSTimer *myTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(actualizarTiempo:) userInfo:nil repeats:YES];
...
- (void)actualizaTiempo:(NSTimer *)timer {
    timeCount -= 1;
    if (timeCount <= 0) {
        [timer invalidate];
    } else {
        [labelTime setText:[self formatTime:timeCount]];
    }
}

Note: formatTime is a function which receive an integer (number of seconds) and returns a NSString with format mm:ss

Everything works ok, that is, the time counts down but the problem is that I have a UITableView in the application and if I touch the table and drag it (to move along the cells) the timer stops until I release my finger from the screen...

Is this behavior normal? If it is, is there any way to avoid it and make the timer work while dragging the table?


Solution

  • By using scheduledTimerWithTimeInterval:, as j.tom.schroeder says, your timer is automatically schedule on the main run loop for the default modes. This will prevent your timer from firing when your run loop is in a non-default mode, e.g., when tapping or swiping.

    The solution, though, is not using a thread, but scheduling your timer for all common modes:

    NSTimer *timer = [NSTimer timerWithTimeInterval:1
                                             target:self
                                           selector:@selector(actualizarTiempo:)
                                           userInfo:nil repeats:YES];
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
    

    Depending on the kind of events you would like to allow without them stopping your timers, you might also consider UITrackingRunLoopMode. For more info about run loop modes, see Apple Docs.