Arka plandan uygulama açılırken ViewDidAppear çağrılmaz


175

Değerim 0 (etiket) olan bir View Controller'ım var ve bu View Controller'ı başka birinden ViewControlleraçtığımda viewDidAppearetikette 20 değerini ayarladım. Bu cezayı çalışır ama benim app kapatıp tekrar benim uygulamayı açmak daha ama değer çünkü değişmez zaman viewDidLoad, viewDidAppearve viewWillAppearhiçbir şey denilen olsun. Uygulamamı açtığımda nasıl arayabilirim? Şundan bir şey yapmam gerekiyor applicationDidBecomeActivemu?


Uygulama etkinleştiğinde yerel bir bildirim gönderebilir ve görünüm denetleyicinizi gözlemci ve güncelleme değerleri olarak ekleyebilirsiniz.
Adil Soomro

Yanıtlar:


314

Olayların tam sırasını merak ediyorum, bir uygulamayı aşağıdaki gibi kullandım: (@Zohaib, sorunuzu cevaplamak için aşağıdaki NSNotificationCenter kodunu kullanabilirsiniz).

// AppDelegate.m

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    NSLog(@"app will enter foreground");
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    NSLog(@"app did become active");
}

// ViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"view did load");

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
}

- (void)appDidBecomeActive:(NSNotification *)notification {
    NSLog(@"did become active notification");
}

- (void)appWillEnterForeground:(NSNotification *)notification {
    NSLog(@"will enter foreground notification");
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    NSLog(@"view will appear");
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    NSLog(@"view did appear");
}

Lansmanda çıktı şöyle görünür:

2013-04-07 09:31:06.505 myapp[15459:11303] view did load
2013-04-07 09:31:06.507 myapp[15459:11303] view will appear
2013-04-07 09:31:06.511 myapp[15459:11303] app did become active
2013-04-07 09:31:06.512 myapp[15459:11303] did become active notification
2013-04-07 09:31:06.517 myapp[15459:11303] view did appear

Arka planı girin ve ön plana tekrar girin:

2013-04-07 09:32:05.923 myapp[15459:11303] app will enter foreground
2013-04-07 09:32:05.924 myapp[15459:11303] will enter foreground notification
2013-04-07 09:32:05.925 myapp[15459:11303] app did become active
2013-04-07 09:32:05.926 myapp[15459:11303] did become active notification

1
Danh, UIApplicationWillEnterForegroundNotification uygulamasını appDidEnterForeground: ile eşlediniz. Bu biraz yanıltıcı değil mi? "İrade" ve "yaptı" dikkat edin. Bu kasıtlı mıydı?
Lubiluk

@Lubiluk - kasıtlı değil. Ben düzenleyeceğim. İyi yakalama.
danh

4
Bu çok faydalı bir cevaptı. Burada bir Swift versiyonu yaptım .
Suresi

Arka plan modunun mükemmel gösterimi!
Marcelo dos Santos

Ana ekran düğmesine iki kez hafifçe dokunduğunuzda ve uygulamayı kapattığınızda etkinlik sırası nedir?
Amjad Husseini

134

Objective-C Kullanımı

Bir kayıt olmalıdır UIApplicationWillEnterForegroundNotificationsenin içinde ViewController'nin viewDidLoadyöntemi ve uygulama arka plandan geri gelir ne zaman Bildirim için kayıtlı yöntemde yapmak istediğimizi yapabiliriz. ViewControlleradlı kullanıcının viewWillAppear veya viewDidAppear uygulaması, arka plandan ön plana geri döndüğünde çağrılmaz.

-(void)viewDidLoad{

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doYourStuff)

  name:UIApplicationWillEnterForegroundNotification object:nil];
}

-(void)doYourStuff{

   // do whatever you want to do when app comes back from background.
}

Kayıt olduğunuz bildirimin kaydını silmeyi unutmayın.

-(void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

Not Eğer senin kayıt eğer viewControlleriçin UIApplicationDidBecomeActiveNotificationdaha sonra yöntem uygulama aktif hale her zaman aranmak, kayıt işlemlerinin tavsiye edilmez viewControllerbu bildirim için.

Swift'i kullanma

Gözlemci eklemek için aşağıdaki kodu kullanabilirsiniz

 override func viewDidLoad() {
    super.viewDidLoad()

     NotificationCenter.default.addObserver(self, selector: "doYourStuff", name: UIApplication.willEnterForegroundNotification, object: nil)
 }

 func doYourStuff(){
     // your code
 }

Gözlemciyi kaldırmak için swift işlevinin deinit işlevini kullanabilirsiniz.

deinit {
    NotificationCenter.default.removeObserver(self)
}

4
Evet bu :) bazen cevap bulmak zor :)
nsgulliver

@nsgulliver El ile bildirimin kaydını iptal etmek zorunda mıyım - (void) dealloc {[[NSNotificationCenter defaultCenter] removeObserver: self]; }. Uygulama benim için yapacak mı?
ios

43

Swift 3.0 ++ sürümü

Gözlerinde farklı viewDidLoad, arka plan eylem açılan bu dinlemek için bildirim merkezinde kayıt

NotificationCenter.default.addObserver(self, selector:#selector(doSomething), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
        

Ardından bu işlevi ekleyin ve gerekli eylemi gerçekleştirin

func doSomething(){
    //...
}

Son olarak, görünüm denetleyiciniz yok edildiğinde bildirim gözlemcisini temizlemek için bu işlevi ekleyin.

deinit {
    NotificationCenter.default.removeObserver(self)
}

VC +1
Mo Zaatar

Bu güzel cevabın diğer birçok benzer / yinelenen SO sorusunda kaçırıldığına inanamıyorum.
Hugo Allexis Cardona

11

Hızlı 4.2. versiyon

viewDidLoadUygulama arka plandan döndüğünde bildirim almak için NotificationCenter'a kaydolun

NotificationCenter.default.addObserver(self, selector: #selector(doSomething), name: UIApplication.willEnterForegroundNotification, object: nil)

Çağrılacak yöntemi uygulayın.

@objc private func doSomething() {
    // Do whatever you want, for example update your view.
}

Bir kez ViewControlleryok edildiğinde gözlemciyi kaldırabilirsiniz . Bu yalnızca iOS9 ve macOS 10.11'in altında gereklidir

deinit {
    NotificationCenter.default.removeObserver(self)
}

1
FYI Bu günlerde artık gözlemcileri kaldırma zahmetine gerek yok eminim ...
Fattie

3

Sadece görünüm kontrolörünüzün UIApplicationWillEnterForegroundNotificationbildirime kaydolmasını ve buna göre tepki vermesini sağlayın .


Bunu nasıl yapacağım? i applicationDidBecomeActive benim viewController çağırdı ama. viewController ya da bunu yapmak için para cezası üst üste?
Zohaib

2
UygulamaDidBecomeActive içinde viewController'ı çağırma (bu birden çok kez çağrıldığından zaten yanlıştır). viewDidLoadİstediğiniz @nsgulliver bildirim için kaydolun önerdi. Sizin viewDidAppearde arayacak doYourStuffistenen değer ile etiket verir.
andreagiavatto

3

UIApplicationWillEnterForegroundNotification için kaydolma riskli olduğunu düşünüyorum çünkü bu bildirime birden fazla denetleyici ile sonuçlanabilir. Bildirim alındığında bu denetleyicilerin hala görünebileceği hiçbir garanti yoktur.

Yaptığım şey: doğrudan uygulamanın delegesi didBecomeActive yönteminden aktif denetleyicide viewDidAppear'ı çağırmaya zorlamak:

Aşağıdaki kodu şuraya ekleyin: - (void)applicationDidBecomeActive:(UIApplication *)application

UIViewController *activeController = window.rootViewController;
if ([activeController isKindOfClass:[UINavigationController class]]) {
    activeController = [(UINavigationController*)window.rootViewController topViewController];
}
[activeController viewDidAppear:NO];

7
Denetleyicinin, dealloc yerine viewWillDisappear içinde UIApplicationWillEnterForegroundNotification için (olması gerektiği gibi) kaydını iptal edeceği garanti edilir. ViewDidAppear'ı çağırmak açıkça bana bir hack gibi görünüyor, anlambilimi bozuyor (kişisel görünüm) ve insanları karıştırabilir (deneyimden).
joakim

3

bunu AppDelegate applicationWillEnterForeground uygulamasına eklemeyi deneyin.

func applicationWillEnterForeground(_ application: UIApplication) {        
    // makes viewWillAppear run
    self.window?.rootViewController?.beginAppearanceTransition(true, animated: false)
    self.window?.rootViewController?.endAppearanceTransition()
}

2

Apple'ın belgelerine göre:

(void)beginAppearanceTransition:(BOOL)isAppearing animated:(BOOL)animated;

Açıklama:
Çocuk denetleyiciye görünüşünün değişmek üzere olduğunu söyler. Özel bir kapsayıcı denetleyicisi uyguluyorsanız, çocuğa görüşlerinin görünmek veya kaybolmak üzere olduğunu söylemek için bu yöntemi kullanın . Çağırmak etmeyin viewWillAppear:, viewWillDisappear:, viewDidAppear:, veya viewDidDisappear:direkt .

(void)endAppearanceTransition;

Açıklama:

Çocuk denetleyiciye görünümünün değiştiğini söyler. Özel bir kapsayıcı denetleyicisi uyguluyorsanız, çocuğa görünüm geçişinin tamamlandığını bildirmek için bu yöntemi kullanın.

Basit kod:

(void)applicationDidEnterBackground:(UIApplication *)application
{

    [self.window.rootViewController beginAppearanceTransition: NO animated: NO];  // I commented this line

    [self.window.rootViewController endAppearanceTransition]; // I commented this line

}

Soru: Nasıl düzelttim?

Ans : Bu çizgi parçasını uygulamada buldum. Bu satırlar, uygulamamın herhangi bir ViewWillAppear bildirimi almamasını sağladı. Ben bu satırları yorum zaman iyi çalışıyor .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.