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
timeraccessible au délégué de l'application et appelertimer.pause ()lorsque l'application appelleapplicationDidEnterBackgroundVous pouvez également ajouter un observateur pour la notification
UIApplication.didEnterBackgroundNotificationet suspendre votre minuterie dans son gestionnaire.Un minuteur s'arrête automatiquement en arrière-plan. Quel est le problème réel?