2013-03-25 4 views
10

Ich habe das Web und Stack Overflow seit Stunden gesucht und kann dieses Problem nicht lösen. Ich hoffe, ihr seht meinen Fehler, weil ich ihn nicht finden kann.Manueller modaler Übergang funktioniert nicht, View Controller ist nicht in der Fensterhierarchie?

Ich habe eine einfache Storyboard-basierte Anwendung, die ich gerade begonnen habe. Der anfängliche ViewController ist eine Instanz von UITabBarController mit den beiden Dummy ViewControllern aus der Vorlage. Beim Start muss ich prüfen, ob das Gerät bei einem externen Dienst angemeldet ist. Wenn nicht, werde ich einen modalen ViewController zeigen, der dem Benutzer erlauben wird, sich zu authentifizieren, wenn das Gerät authentifiziert wird, dann zeige ich nur den FirstViewController.

Die folgenden Schritte sind alles, was ich seit der Erstellung des Projekts durchgeführt haben:

  1. die AuthenticateViewController Szene auf der
  2. Storyboard erstellen
  3. für AuthenticateViewController erstellen Code-Dateien, und ordnen sie der entsprechenden Szene
  4. erstellen Codedateien für eine UITabBarController-Unterklasse, und verknüpfen Sie die ursprüngliche UITabBarController-Szene mit dieser neuen Unterklasse.
  5. Erstellen Sie ein neues Segment auf dem Storyboard von der UITabBarControllerszene zum Authenti cateViewController Szene
  6. manuell segue von viewDidLoad in der Unterklasse UITabBarController nennen

Wenn ich die Anwendung der modale segue läuft nicht, der erste Viewcontroller des UITabBarController Feuer gezeigt, und ich erhalte die folgende Ausgabe in XCode :

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

Relevanter Code unten, tatsächlich der einzige Code, den ich bis jetzt hinzugefügt habe. Bitte lassen Sie mich wissen, wenn Screenshots oder zusätzliche Informationen nützlich wären. Vielen Dank im Voraus für Ihre Hilfe.

EPTabBarController, Unterklasse von 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 

Antwort

14

Das Problem ist, innerhalb

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

Sie versuchen, eine andere Ansicht (AuthenticateViewController), während die aktuelle Ansicht zu präsentieren (EPTabBarController) noch nicht geladen in die Fensterhierarchie.

Lassen Sie zuerst Ihre EPTabBarController in Fensterhierarchie laden und dann AuthenticateViewController präsentieren.

Geben Sie diesem einen Versuch

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

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

Das funktioniert, aber scheint mir eine eher unelegante Lösung. Ist das der einzige Weg dies zu erreichen? Sollte der Aufruf 'performSegueWithIdentifer:' an einen anderen Ort verschoben werden? – blundin

+0

Hey @blundin bitte versuche nachAbsetzen: 0.0 und check. lass mich wissen, ob funktioniert glatt –

+1

Ja, das funktioniert reibungslos. Vielen Dank. – blundin

2

Wenn Sie wirklich in Kontrolle sein wollen, so etwas wie verwenden:

@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 

Das die Segue pushToMainView ausgelöst wird, wenn Sie Nachricht [controller pushToMainView] aber zurückhält, bis die Ansicht geladen ist.

3

Wie wäre es, Ihren Code einfach in viewDidAppear aufzurufen?

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

Allerdings bin ich immer noch nicht zufrieden mit diesen Lösungen, weil die ursprüngliche Ansicht noch für einen Bruchteil einer Sekunde angezeigt wird.

Haben Sie eine Idee, wie Sie das neue Modal anzeigen können, ohne zuerst die ursprüngliche Ansicht anzuzeigen?

Verwandte Themen