2013-03-25 11 views
10

Ho cercato sul Web e Stack Overflow per ore e non riesco a risolvere questo problema. Spero che tutti vedano il mio errore, perché non riesco a trovarlo.Il passaggio modale manuale non funziona, View Controller non è nella gerarchia delle finestre?

Ho una semplice applicazione basata su storyboard che ho appena iniziato. Il ViewController iniziale è un'istanza di UITabBarController con i due ViewController fittizi del modello. All'avvio ho bisogno di verificare se il dispositivo è connesso a un servizio esterno. In caso contrario, mostrerò un ViewController modale che permetterà all'utente di autenticare, se il dispositivo è autenticato, mostrerò solo il FirstViewController.

I seguenti passaggi sono tutto ciò che ho fatto dopo la creazione del progetto:

  1. Creare la scena AuthenticateViewController sulla Storyboard
  2. Creare file di codice per AuthenticateViewController, e assegnarli alla scena corrispondente
  3. Crea file di codice per una sottoclasse UITabBarController e associare la scena UITabBarController iniziale alla nuova sottoclasse
  4. Creare un nuovo seguito sullo storyboard dalla scena UITabBarController agli Authenti cateViewController scena
  5. chiamare manualmente la segue da viewDidLoad nella sottoclasse UITabBarController

Quando eseguo l'applicazione segue modale non scatta, viene mostrato il primo ViewController del UITabBarController, e ottengo il seguente output in XCode :

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

Codice pertinente riportato di seguito, in effetti l'unico codice che ho aggiunto fino ad ora. Per favore fatemi sapere se screenshot o informazioni aggiuntive sarebbero utili. Grazie in anticipo per il vostro aiuto.

EPTabBarController, sottoclasse di 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 

risposta

14

La questione si trova all'interno

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

si sta tentando di presentare un'altra vista (AuthenticateViewController), mentre la visualizzazione corrente (EPTabBarController) non è ancora caricato in la gerarchia delle finestre.

Quindi, prima di caricare il file EPTabBarController nella gerarchia delle finestre e quindi presentare AuthenticateViewController.

dare una prova

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

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

Questo funziona, ma mi sembra una soluzione piuttosto inelegante. È questo l'unico modo per realizzare questo? La chiamata 'performSegueWithIdentifer:' dovrebbe essere messa altrove? – blundin

+0

Ehi, @blundin, prova a impostare afterDelay: 0.0 e controlla. fammi sapere se funziona senza problemi –

+1

Sì, funziona perfettamente. Grazie. – blundin

2

Quando si vuole veramente essere in controllo, usare qualcosa di simile a questo:

@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 

Questa sparerà il Segue pushToMainView quando si messaggio [controller pushToMainView] ma trattiene, fino a quando la vista non viene caricata.

3

Che ne dici di chiamare semplicemente il codice in viewDidAppear?

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

Tuttavia, sono ancora insoddisfatto di queste soluzioni, perché la vista originale mostra ancora per una frazione di secondo.

Qualche idea su come mostrare la nuova modale senza mostrare prima la vista originale?

Problemi correlati