2015-01-17 20 views
6

Mam timer, który uruchamia się, aby ponownie uruchomić alarm po jego uruchomieniu.NSTimer nie odpala, gdy NSMenu jest otwarte w Swift

alarm = NSTimer.scheduledTimerWithTimeInterval(
    60 * minutesConstant + secondsConstant, 
    target:self, 
    selector: Selector("endSession"), 
    userInfo: nil, 
    repeats:false) 

Jego funkcja wybierak ustawia flagę trybu i zwraca pierwotną funkcję, ustawić alarm nowych minutach i sekundach stałych, a także wysyła powiadomienia użytkownika, że ​​sesja została wznowiona.

Mam menu, które zostanie zaktualizowany z pozostałego czasu

enter image description here

Więc byłem otwierając go, aby sprawdzić, że mój alarm rzeczywiście restart, i że zgłoszenie pokazuje raz spadnie do zera . To działa, ale kiedy mam otwarte menu i zejdzie do zera, po prostu pozostaje o 0:00, a timer nie uruchamia się, dopóki nie kliknę menu, w którym to momencie natychmiast wyświetla powiadomienie i resetuje timer zgodnie z przeznaczeniem .

Jak wymusić uruchomienie timera, gdy menu jest otwarte? To nie jest wielka sprawa, ale nie chcę, aby użytkownik mylił się z sesją, po prostu się zawiesza, jeśli obserwują, jak zegar się kończy.

Odpowiedz

17

Po prostu trzeba dodać licznik do głównego runloop następująco:

Swift 3

RunLoop.main.add(alarm, forMode: .commonModes) 

Swift 2.x

NSRunLoop.mainRunLoop().addTimer(alarm, forMode: NSRunLoopCommonModes) 
+1

To jest poprawny. Jest to zasadniczo to, co można zobaczyć w menu na lotnisku, ponieważ okresowo skanuje SSID – uchuugaka

+1

W szczególności pętla uruchamiania działa w 'NSEventTrackingRunLoopMode' podczas śledzenia menu. Jeśli twój timer jest tylko w 'NSDefaultRunLoopMode', nie uruchomi się. Oba te tryby znajdują się w zestawie 'NSRunLoopCommonModes', więc dodanie timera do tego pseudo-trybu pozwala mu strzelać w obu przypadkach (i innych). –

+0

Doskonale, dzięki za odpowiedź i jasne wyjaśnienie! –