0
votes

Comment mettre en pause la minuterie () lorsque l'application passe en arrière-plan

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 commentaires

vous devrez rendre timer accessible au délégué de l'application et appeler timer.pause () lorsque l'application appelle applicationDidEnterBackground


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?


3 Réponses :


0
votes

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) {

    }

}


0 commentaires

0
votes

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()
    }


0 commentaires

2
votes

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()
}


0 commentaires