2012-07-29 35 views
15

我有一个带倒数计时器的应用程序。我再也忍受不了与从定时器这样调用功能更新标签使其:NSTimer在拖动UITableView时不工作

... 
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]]; 
    } 
} 

注:formatTime是收到一个整数(秒为单位)的函数,返回的NSString与格式毫米:ss

一切正常,也就是说,时间倒计时,但问题是,我有一个UITableView在应用程序中,如果我触摸表并拖动它(沿细胞移动)计时器停止,直到我从屏幕释放我的手指...

这种行为是否正常?如果是这样,是否有任何方法可以避免它,并在拖动表格时使计时器工作?

回答

25

通过使用scheduledTimerWithTimeInterval:,正如j.tom.schroeder所说,您的计时器会自动安排在默认模式的主运行循环中。当您的运行循环处于非默认模式时,例如点击或滑动时,这将防止您的计时器触发。

的解决方案,虽然没有使用一个线程,而是安排你的所有常见的模式定时器:

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

根据这类活动你想允许没有他们停止你的定时器,你可能也考虑UITrackingRunLoopMode。有关运行循环模式的更多信息,请参见Apple Docs

+0

非常感谢您的帮助,它适用于此解决方案。我会仔细看看循环模式,以获得更适合我的事件的模式 – rai212 2012-07-30 14:54:44

+1

不要忘记'[timer invalidate];'on viewWillDisappear'或任何其他方法,或者您将一次又一次地启动计时器。 – skornos 2015-07-21 10:26:56

0

这是正常行为。 scheduledTimerWithTimeInterval:调度在当前运行循环上,所以任何与UITableView的交互都会阻止调用actualizarTiempo:方法。使用NSThread方法detachNewThreadSelector:toTarget:withObjectsleepForTimeInterval在单独的线程上执行actualizarTiempo:

+0

真正的问题是相关的事实是,计时器与当前运行的循环。在不同的循环模式下使用NSRunLoop可以解决问题。谢谢 – rai212 2012-07-30 14:57:49

3

继承人的雨燕版本:

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

Swift 3+版本:RunLoop.main.add(timer,forMode:RunLoopMode.commonModes) – 2017-03-04 01:47:01