Je suis donc bloqué, je suis en train de créer une application de bingo et je veux que l'application arrête le chronomètre lorsque l'application passe en arrière-plan. mon code ressemble à ceci
var timer = Timer() func ViewDidLoad(){ // other stuff timer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(numberPicker), userInfo: nil, repeats: true) }
Dans d'autres articles que j'ai lus à ce sujet, j'ai vu des gens recommander de définir le minuteur comme une variable faible. Lorsque j'essaye, mon application se bloque lorsqu'elle essaie de faire le chronomètre.
3 Réponses :
Essayez ceci. Le minuteur sera également redémarré lorsque l'application reviendra de l'arrière-plan.
class ViewController: UIViewController { var timer = Timer() var timerPaused = false override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default .addObserver(self, selector: #selector(applicationDidEnterBackground), name: UIApplication.didEnterBackgroundNotification, object: nil) NotificationCenter.default .addObserver(self, selector: #selector(applicationDidBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil) timer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(numberPicker), userInfo: nil, repeats: true) } @objc func applicationDidEnterBackground(_ notification: Notification) { if !timerPaused { timer.invalidate() timerPaused = true } } @objc func applicationDidBecomeActive(_ notification: Notification) { if timerPaused { timer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(numberPicker), userInfo: nil, repeats: true) timerPaused = false } } @objc func numberPicker(_ sender: Any) { } }
SWIFT 5:
override func viewDidLoad() { super.viewDidLoad() let notificationCenter = NotificationCenter.default notificationCenter.addObserver(self, selector: #selector(appMovedToBackground), name: UIApplication.willResignActiveNotification, object: nil) } @objc func appMovedToBackground() { timer.invalidate() }
Une solution moderne est un DispatchSourceTimer
qui peut être suspendu et repris.
Les deux observateurs de notification utilisent également une API moderne basée sur des blocs swifty , pas de @ objc
nécessaire.
let timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global()) override func viewDidLoad() { super.viewDidLoad() timer.schedule(deadline: .now() + .seconds(5), repeating: 5.0) timer.setEventHandler { print("Timer fired") } NotificationCenter.default.addObserver(forName: UIApplication.didEnterBackgroundNotification, object: nil, queue: .main) { [weak self] _ in self?.timer.suspend() } NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: .main) { [weak self] _ in self?.timer.resume() } timer.activate() }
vous devrez rendre
timer
accessible au délégué de l'application et appelertimer.pause ()
lorsque l'application appelleapplicationDidEnterBackground
Vous pouvez également ajouter un observateur pour la notification
UIApplication.didEnterBackgroundNotification
et suspendre votre minuterie dans son gestionnaire.Un minuteur s'arrête automatiquement en arrière-plan. Quel est le problème réel?