NSTimer not working while dragging a UITableView

我的梦境 提交于 2019-12-18 03:14:23

问题


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?


回答1:


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.




回答2:


Heres the Swift version:

Swift 2

var timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "removeFromSuperview", userInfo: nil, repeats: false)
NSRunLoop.mainRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes)

Swift 3, 4, 5

var timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(removeFromSuperview), userInfo: nil, repeats: false)
RunLoop.main.add(timer, forMode: RunLoop.Mode.common)



回答3:


This is normal behavior. scheduledTimerWithTimeInterval: schedules on the current run loop, so any interaction with the UITableView will block the actualizarTiempo: method from being called. Use the NSThread methods detachNewThreadSelector:toTarget:withObject and sleepForTimeInterval to perform actualizarTiempo: on a separate thread.




回答4:


Swift version 4+:

var timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.TimerController), userInfo: nil, repeats: true)
RunLoop.main.add(timer, forMode: RunLoopMode.commonModes)

if you want to repeat for example as a counter then set repeat = true else = false



来源:https://stackoverflow.com/questions/11712546/nstimer-not-working-while-dragging-a-uitableview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!