Ich habe einen Ansichts-Controller, der einen verwendet NSTimer
, um Code auszuführen.
Was ist der beste Weg, um zu erkennen, wann die App in den Hintergrund tritt, damit ich den Timer anhalten kann?
Antworten:
Sie können jede Klasse, die interessiert ist, wenn die App in den Hintergrund tritt, Benachrichtigungen erhalten. Dies ist eine gute Alternative zum Koppeln dieser Klassen mit dem AppDelegate.
Bei der Initialisierung dieser Klassen:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillTerminate:) name:UIApplicationWillTerminateNotification object:nil];
Antworten auf die Benachrichtigungen
-(void)appWillResignActive:(NSNotification*)note
{
}
-(void)appWillTerminate:(NSNotification*)note
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillTerminateNotification object:nil];
}
In Swift 4.0
override func viewDidLoad() {
super.viewDidLoad()
let app = UIApplication.shared
//Register for the applicationWillResignActive anywhere in your app.
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.applicationWillResignActive(notification:)), name: NSNotification.Name.UIApplicationWillResignActive, object: app)
}
@objc func applicationWillResignActive(notification: NSNotification) {
}
In Ihren Anwendungen AppDelegate wird die (void)applicationDidEnterBackground:(UIApplication *)application
Methode von iOS aufgerufen. Sie können Ihren Timer dort anhalten.
Für diejenigen, die dies in Swift tun möchten:
Am init
:
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(applicationWillResignActive), name: UIApplicationWillResignActiveNotification, object: nil)
Am deinit
:
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIApplicationWillResignActiveNotification, object: nil)
Antwort auf die Benachrichtigung:
dynamic private func applicationWillResignActive() {
// Do things here
}
Apple empfiehlt uns, dynamische Versand- und Objective-C-Selektoren in Swift nach Möglichkeit zu vermeiden. Dies ist jedoch immer noch der bequemste Weg, dies zu tun.
In schnellem 4.1:
Ich benutze die Verschlussversion:
var observer: NSObjectProtocol!
// inside init or viewDidLoad:
observer = NotificationCenter.default.addObserver(forName: .UIApplicationWillResignActive, object: nil, queue: nil) { _ in
print("willResignActive")
}
deinit {
NotificationCenter.default.removeObserver(observer)
}
Die addObserver
Methode gibt ein undurchsichtiges Objekt zurück, das irgendwann entfernt werden muss.
Nur eine Randnotiz: Wenn Sie einen Controller A registrieren, um im Hintergrund benachrichtigt zu werden, achten Sie darauf, dass er auch dann aufgerufen wird, wenn Sie (z. B.) einen zweiten Controller B drücken und B anzeigen: Wenn dieses Verhalten nicht korrekt ist ist besser zu registrieren / abmelden in
didAppear / WillDisappear.
- (void)applicationWillResignActive:(UIApplication *)application
auf Ihrem App-Delegaten. Sie können sich auch für die UIApplicationWillResignActiveNotification
Benachrichtigung für andere Objekte registrieren .
Sie müssen den Timer jedoch nicht unbedingt anhalten. Wenn Sie nichts tun, wird die App trotzdem in den Ruhezustand versetzt und führt keinen Code aus. Vermutlich wird Ihr Timer ausgelöst, wenn Sie wieder aktiv werden (falls Sie dies tun). Wenn Sie etwas Besonderes tun müssen, gibt es Delegierungsmethoden und Benachrichtigungen, für die Sie sich ebenfalls registrieren können.
Swift 4:
init() {
NotificationCenter.default.addObserver(self,
selector: #selector(applicationWillResignActive),
name: NSNotification.Name.UIApplicationWillResignActive,
object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self,
name: NSNotification.Name.UIApplicationWillResignActive,
object: nil)
}
@objc private func applicationWillResignActive() {
self.header.blur.effect = nil
}
Dies ist eine bessere Lösung mit Verschluss
Beobachter erklären
var backgroundObserver: NSObjectProtocol?
Initialisieren Sie den Beobachter in viewDidLoad
backgroundObserver = NotificationCenter.default.addObserver(forName: UIApplication.willResignActiveNotification, object: nil, queue: .main) { [weak self] notification in
// Do what you want to do when app would go to background/ resign active
}
Vergessen Sie nicht, den Beobachter in deinit zu entfernen
deinit {
if let observer = backgroundObserver {
NotificationCenter.default.removeObserver(observer)
}
}
@selector
, dh Ersetzen@selector(appWillResignActive)
mit@selector(appWillResignActive:)
(und gleiche gilt für@selector(appWillTerminate:)
).