2012-07-29 62 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