2010-09-03 6 views
146

Mam protokół UIApplicationDelegate w mojej głównej klasie AppDelegate.m, z określoną metodą applicationDidBecomeActive.Obsługa aplikacjiDidBecomeActive - "W jaki sposób kontroler widoku może odpowiedzieć na aktywację aplikacji?"

Chcę wywołać metodę, gdy aplikacja zwraca z tła, ale metoda jest w innym kontroler widoku. Jak mogę sprawdzić, który kontroler widoku jest aktualnie wyświetlany w metodzie applicationDidBecomeActive, a następnie wykonać wywołanie metody w tym kontrolerze?

Odpowiedz

275

Każda klasa w aplikacji może zostać "obserwatorem" dla różnych powiadomień w aplikacji. Po utworzeniu (lub załadowaniu) kontrolera widoku należy go zarejestrować jako obserwatora dla obiektu UIApplicationDidBecomeActiveNotification i określić, z której metody ma zostać wywołane powiadomienie wysyłane do aplikacji.

[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(someMethod:) 
              name:UIApplicationDidBecomeActiveNotification object:nil]; 

Nie zapomnij posprzątać po sobie! Pamiętaj, aby usunąć siebie jako obserwatora, gdy widok odchodzi:

[[NSNotificationCenter defaultCenter] removeObserver:self 
               name:UIApplicationDidBecomeActiveNotification 
               object:nil]; 

Więcej informacji o Notification Center.

+0

Doskonały. Nie myślałem o użyciu 'NSNotificationCenter'. Dziękuję Ci! – Calvin

+3

Po prostu literówka w tym wierszu kodu (brak "nazwy"): [[NSNotificationCenter defaultCenter] addObserver: selektor własny: @selector (someMethod :) name: UIApplicationDidBecomeActiveNotification object: nil]; – Johnus

+0

@Johnus - dzięki za połów. Zaktualizowano moją odpowiedź. –

15

Swift 2 równoważników:

let notificationCenter = NSNotificationCenter.defaultCenter() 

// Add observer: 
notificationCenter.addObserver(self, 
    selector:Selector("applicationWillResignActiveNotification"), 
    name:UIApplicationWillResignActiveNotification, 
    object:nil) 

// Remove observer: 
notificationCenter.removeObserver(self, 
    name:UIApplicationWillResignActiveNotification, 
    object:nil) 

// Remove all observer for all notifications: 
notificationCenter.removeObserver(self) 

// Callback: 
func applicationWillResignActiveNotification() { 
    // Handle application will resign notification event. 
} 
+0

Najlepsze miejsce na umieszczenie 'removeObserver' w Swift:' deinit' method. –

+0

Zasadniczo nie zaleca się dostępu do funkcji deinit; w tym momencie "ja" jest pomiędzy przyznaniem pełnej alokacji a zwolnieniem – Zorayr

+0

Gdzie wtedy usunąłbyśObserwer? –

32

Swift 3, 4 identyczne:

dodanie obserwator

NotificationCenter.default.addObserver(self, 
    selector: #selector(applicationDidBecomeActive), 
    name: .UIApplicationDidBecomeActive, 
    object: nil) 

usuwania obserwator

NotificationCenter.default.removeObserver(self, 
    name: .UIApplicationDidBecomeActive, 
    object: nil) 

zwrotna

@objc func applicationDidBecomeActive() { 
    // handle event 
} 
+0

gdzie mam to nazwać? –

+0

@ user8169082, dodajesz obserwatora, gdziekolwiek potrzebujesz, aby zacząć otrzymywać powiadomienia. Możesz na przykład dodać go do 'viewDidLoad' lub' viewWillAppear: animated'. Możesz usunąć obserwatora, gdy nie potrzebujesz już powiadomień lub gdy instancja obserwatora zostanie zwolniona w metodzie deinit – igrek

1

Z Swift 4, Apple informuje, za pośrednictwem nowego ostrzeżenia kompilatora, że ​​unikamy używania #selector w tym scenariuszu. Poniżej znajduje się znacznie bezpieczniejszy sposób do osiągnięcia tego celu:

pierwsze, stworzenie leniwe var które mogą być wykorzystane przez zgłoszenia:

lazy var didBecomeActive: (Notification) -> Void = { [weak self] _ in 
    // Do stuff 
} 

Jeśli wymagają rzeczywistej powiadomienie być włączone, wystarczy zastąpić _ z notification.

Następnie skonfigurowaliśmy powiadomienie, aby obserwować, jak aplikacja staje się aktywna.

func setupObserver() { 
    _ = NotificationCenter.default.addObserver(forName: .UIApplicationDidBecomeActive, 
               object: nil, 
               queue: .main, 
               using: didBecomeActive) 
} 

Dużą zmianą jest to, że zamiast wywoływania #selector, obecnie nazywamy var utworzonego powyżej. Może to wyeliminować sytuacje, w których pojawią się niepoprawne błędy selektora.

Na koniec usuwamy obserwatora.

func removeObserver() { 
    NotificationCenter.default.removeObserver(self, name: .UIApplicationDidBecomeActive, object: nil) 
} 
Powiązane problemy