2016-01-09 12 views
8

Chcę wyświetlić komunikat alertu z metody viewDidLoad() z ViewController.m zamiast z metody viewDidAppear().Wyświetl komunikat alertu z viewDidLoad

Oto mój kod:

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    //A SIMPLE ALERT DIALOG 
    UIAlertController *alert = [UIAlertController 
           alertControllerWithTitle:@"My Title" 
           message:@"Enter User Credentials" 
           preferredStyle:UIAlertControllerStyleAlert]; 


    UIAlertAction *cancelAction = [UIAlertAction 
           actionWithTitle:NSLocalizedString(@"Cancel", @"Cancel action") 
           style:UIAlertActionStyleCancel 
           handler:^(UIAlertAction *action) 
           { 
            NSLog(@"Cancel action"); 
           }]; 

    UIAlertAction *okAction = [UIAlertAction 
          actionWithTitle:NSLocalizedString(@"OK", @"OK action") 
          style:UIAlertActionStyleDefault 
          handler:^(UIAlertAction *action) 
          { 
           NSLog(@"OK action"); 
          }]; 

    [alert addAction:cancelAction]; 
    [alert addAction:okAction]; 
    [self presentViewController:alert animated:YES completion:nil]; 
} 

i otrzymuję ten błąd:

Warning: Attempt to present <UIAlertController: 0x7fbc58448960> on <ViewController: 0x7fbc585a09d0> whose view is not in the window hierarchy!

+1

Prawdopodobny duplikat [którego widok nie znajduje się w hierarchii okna] (http://stackoverflow.com/questions/11862883/whose-view-is-not-in-the-window-hierarchy) – Woodstock

+0

@Woodstock moje pytanie jest inny ... –

Odpowiedz

12

OK, nie błąd, problem polega na tym, że w viewDidLoad hierarchia widoków nie jest w pełni ustawiona. Jeśli używasz viewDidAppear, hierarchia jest ustawiona.

Jeśli naprawdę chcesz wywołać ten alert w viewDidLoad można to zrobić poprzez owinięcie rozmowy prezentacji w tym bloku GCD spowodować niewielkie opóźnienie, czekając na następną pętlę wykonywania, jednak proponuję nie robić (to brzydki).

dispatch_async(dispatch_get_main_queue(),^{ 
    [self presentViewController:alert animated:YES completion:nil]; 
}); 
+1

Dziękuję za odpowiedź .. To działa :) –

+1

moja przyjemność, tylko uwaga, że ​​chociaż powyższe działa, to chyba Apple nie zamierzał wyświetlać alertów w viewDidLoad, ponieważ jest bardzo wcześnie w cyklu życia viewController. – Woodstock

+0

Ok .. Zachowałem ten punkt w moim umyśle –

0

Trzeba umieścić kontroler nawigacji i przedstawi regulatorowi

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    //A SIMPLE ALERT DIALOG 


    UIAlertController *alert = [UIAlertController 
          alertControllerWithTitle:@"My Title" 
          message:@"Enter User Credentials" 
          preferredStyle:UIAlertControllerStyleAlert]; 


    UIAlertAction *cancelAction = [UIAlertAction 
          actionWithTitle:NSLocalizedString(@"Cancel", @"Cancel action") 
          style:UIAlertActionStyleCancel 
          handler:^(UIAlertAction *action) 
          { 
           NSLog(@"Cancel action"); 
          }]; 

    UIAlertAction *okAction = [UIAlertAction 
         actionWithTitle:NSLocalizedString(@"OK", @"OK action") 
         style:UIAlertActionStyleDefault 
         handler:^(UIAlertAction *action) 
         { 
          NSLog(@"OK action"); 
         }]; 

    [alert addAction:cancelAction]; 
    [alert addAction:okAction]; 

    [self.navigationController presentViewController:alert animated:NO completion:nil]; 
    // [self presentViewController:cameraView animated:NO completion:nil]; //this will cause view is not in the window hierarchy error 

} 

OR

[self.view addSubview:alert.view]; 
    [self addChildViewController:alert]; 
    [alert didMoveToParentViewController:self]; 
+0

Próbuję twój sugerowany kod. ale aplikacja ulega awarii po kliknięciu dowolnego przycisku, np. OK, Anuluj .. a także Alert Box jest wyświetlany na górze po lewej stronie –

+0

@ShivaniArorra Zaktualizowałem mój ans sprawdź to, co musisz zrobić '[self.navigationController presentViewController: alert animowany : BRAK zakończenia: zero); ' –

8

przeniesienie tego wywołania do metody viewDidAppear:.

+0

masz rację, myślę, że to powinno być możliwe do wywołania z viewDidLoad. – Woodstock

+0

ale chcę zadzwonić do formularza viewDidLoad: metoda –

-1

Swift 3 iOS 10, kiedyś kolejkę operacji umieścić blok kodu, który aktualizuje interfejs do głównego wątku.

import UIKit 

class ViewController2: UIViewController { 

var opQueue = OperationQueue() 

override func viewDidLoad() { 
    super.viewDidLoad() 
     let alert = UIAlertController(title: "MESSAGE", message: "HELLO WORLD!", preferredStyle: UIAlertControllerStyle.alert) 
     // add an action (button, we can add more than 1 buttons) 
     alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil)) 
     // show the alert 
     self.opQueue.addOperation { 
      // Put queue to the main thread which will update the UI 
      OperationQueue.main.addOperation({ 
       self.present(alert, animated: true, completion: nil) 
      }) 
     } 
    } 
} 

W skrócie używamy async. Pozwala to na wyświetlanie komunikatu alertu zgodnie z oczekiwaniami (nawet gdy jesteśmy w viewDidLoad()).

+0

To faktycznie dodaje blok do lokalnej kolejki operacji, która dodaje kolejny blok do głównej kolejki operacji, która następnie wyświetla alert. Bardziej normalne jest używanie w tym celu kolejki wysyłkowej: 'DispatchQueue.main.async {...}'. –

Powiązane problemy