2013-03-25 8 views
10

Przez wiele godzin szukałem w Internecie i przepełnienia stosu i nie mogę rozwiązać tego problemu. Mam nadzieję, że wszyscy zobaczyliście mój błąd, ponieważ po prostu nie mogę go znaleźć.Ręczne przejście modalne nie działa, kontroler widoku nie znajduje się w hierarchii okna?

Mam prostą aplikację opartą na storyboardzie, którą właśnie zacząłem. Początkowy ViewController jest instancją UITabBarController z dwoma fałszywymi ViewControllerami z szablonu. Po uruchomieniu muszę sprawdzić, czy urządzenie jest zalogowane do usługi zewnętrznej. Jeśli nie, pokażę modalny ViewController, który pozwoli użytkownikowi uwierzytelnić, jeśli urządzenie jest uwierzytelnione, po prostu pokażę FirstViewController.

następujące kroki są wszystko zrobiłem od tworzenia projektu:

  1. utworzyć scenę AuthenticateViewController na Storyboard
  2. Tworzenie plików kodu dla AuthenticateViewController i przypisać je do odpowiedniej sceny
  3. Tworzenie pliki kodu dla podklasy UITabBarController i powiąż początkową scenę UITabBarController z nową podklasą
  4. Utwórz nową scenę w serii ujęć ze sceny UITabBarController do Authenti cateViewController scena
  5. ręcznie wywołać segue od viewDidLoad w podklasie UITabBarController

Kiedy uruchomić aplikację modalna segue nie ogień, jest pokazany pierwszy ViewController z UITabBarController i uzyskać następujący wynik w Xcode :

Warning: Attempt to present <AuthenticateViewController: 0x83c0c10> on <EPTabBarController: 0x83be600> whose view is not in the window hierarchy! 

Odpowiedni kod poniżej, w rzeczywistości jedyny kod, który dodałem do tej pory. Daj mi znać, jeśli przydatne będą zrzuty ekranu lub dodatkowe informacje. Z góry dziękuje za twoją pomoc.

EPTabBarController, podklasa UITabBarController:

#import "EPTabBarController.h" 
#import "AuthenticateViewController.h" 

@interface EPTabBarController() 

@end 

@implementation EPTabBarController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    [self performSegueWithIdentifier:@"authenticationSegue" sender:self]; 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

@end 

Odpowiedz

14

Problem jest wewnątrz

- (void)viewDidLoad 
{ 
    [super viewDidLoad];  
    [self performSegueWithIdentifier:@"authenticationSegue" sender:self]; 
} 

próbujesz przedstawić inny pogląd (AuthenticateViewController) podczas bieżącego widoku (EPTabBarController) nie jest jeszcze załadowany hierarchia okna.

Najpierw niech Twój EPTabBarController zostanie załadowany w hierarchii okna, a następnie przedstawi AuthenticateViewController.

spróbuj tego

- (void)viewDidLoad 
{ 
    [super viewDidLoad];   
    [self performSelector:@selector(loadAuthenticateViewController) 
       withObject:nil 
       afterDelay:1.0]; 
} 

-(void)loadAuthenticateViewController 
{ 
    [self performSegueWithIdentifier:@"authenticationSegue" sender:self]; 
} 
+1

To działa, ale wydaje mi się dość nieeleganckim rozwiązaniem. Czy to jedyny sposób, aby to osiągnąć? Czy wywołanie "performSegueWithIdentifer:" powinno być umieszczone gdzie indziej? – blundin

+0

Hej @ Blundin, spróbuj ustawić afterDelay: 0.0 i sprawdź. daj mi znać, jeśli działa gładko. –

+1

Tak, to działa sprawnie. Dziękuję Ci. – blundin

2

Kiedy naprawdę chcą mieć kontrolę, użyć czegoś takiego:

@implementation UeInitialisationViewController 
BOOL didLoad; 
BOOL wantPush; 

- (id)init { 
    self = [super init]; 
    if (self) { didLoad = NO; wantPush = NO; } 
    return self; 
} 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    didLoad = YES; 
    if (wantPush == YES) 
     [self performSelector:@selector(pushToMainView) 
        withObject:nil afterDelay:0.0001]; 
} 

- (void)pushToMainView { 
    if (didLoad == YES) 
     [self performSegueWithIdentifier:@"pushToMainView" sender:self]; 
    else 
     wantPush = YES; 
} 
@end 

Będzie ogień na Segue pushToMainView kiedy wiadomość [controller pushToMainView] ale powstrzymuje, dopóki widok nie zostanie załadowany.

3

Co powiesz na proste wywołanie kodu w viewDidAppear?

- (void)viewDidAppear 
{ 
    [super viewDidAppear];  
    [self performSegueWithIdentifier:@"authenticationSegue" sender:self]; 
} 

Jednak nadal nie jestem usatysfakcjonowany tymi rozwiązaniami, ponieważ oryginalny widok nadal pojawia się na ułamek sekundy.

Masz pomysł na pokazanie nowego modalu bez pokazywania oryginalnego widoku?