2011-12-19 7 views
26

Ho un UITabBarController, quando si esegue inizialmente, voglio sovrapporre un controller di visualizzazione login ma ho ricevuto un errore.Chiamate sbilanciate per iniziare/terminare transizioni di apparenza per UITabBarController

Chiamate sbilanciate per iniziare/terminare transizioni di aspetto per < UITabBarController: 0x863ae00>.

Di seguito è riportato il codice.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    // Override point for customization after application launch. 
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; 

    // Override point for customization after application launch. 

    UIViewController *lessonVC = [[[LessonViewController alloc] initWithNibName:@"LessonViewController" bundle:nil] autorelease]; 

    UIViewController *programVC = [[[ProgramViewController alloc] initWithNibName:@"ProgramViewController" bundle:nil] autorelease]; 

    UIViewController *flashcardVC = [[[FlashCardViewController alloc] initWithNibName:@"FlashCardViewController" bundle:nil] autorelease]; 

    UIViewController *moreVC = [[[MoreViewController alloc] initWithNibName:@"MoreViewController" bundle:nil] autorelease]; 

    UINavigationController *lessonNVC = [[[UINavigationController alloc] initWithRootViewController:lessonVC] autorelease]; 

    UINavigationController *programNVC = [[[UINavigationController alloc] initWithRootViewController:programVC] autorelease]; 

    UINavigationController *flashcardNVC = [[[UINavigationController alloc] initWithRootViewController:flashcardVC] autorelease]; 

    UINavigationController *moreNVC = [[[UINavigationController alloc] initWithRootViewController:moreVC] autorelease]; 

    self.tabBarController = [[[UITabBarController alloc] init/*WithNibName:nil bundle:nil*/] autorelease]; 
    self.tabBarController.viewControllers = [NSArray arrayWithObjects:lessonNVC, programNVC, flashcardNVC, moreNVC, nil]; 
    self.tabBarController.selectedIndex = 0; 
    self.window.rootViewController = self.tabBarController; 

    [self.window makeKeyAndVisible]; 

    if (![[ZYHttpRequest sharedRequest] userID]) 
    { 
     // should register or login firstly 
     LoginViewController *loginVC = [[LoginViewController alloc] initWithNibName:@"LoginViewController" 
                      bundle:nil]; 
     loginVC.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; 
     [self.tabBarController presentModalViewController:loginVC animated:YES]; 
     ZY_SAFE_RELEASE(loginVC); 
    } 

    return YES; 
} 

Chiunque può aiutarmi? Grazie in anticipo!

+0

Inoltre, ho controllato questo [http://stackoverflow.com/q/7886096/527539]. Ma senza fortuna. – ZYiOS

risposta

76

è necessario attendere per presentare il controller di vista modale fino al prossimo ciclo di esecuzione. Ho finito per usare un blocco (per rendere le cose più semplici) per programmare la presentazione per il prossimo ciclo di esecuzione:

Aggiornamento:
Come accennato da Mark Amery sotto, solo un semplice dispatch_async opere, non c'è alcuna necessità di un timer:

dispatch_async(dispatch_get_main_queue(), ^(void){  
    [self.container presentModalViewController:nc animated:YES]; 
}); 

/* Present next run loop. Prevents "unbalanced VC display" warnings. */ 
double delayInSeconds = 0.1; 
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
    [self.container presentModalViewController:nc animated:YES]; 
}); 
+4

Non c'è bisogno di un timer qui, almeno nel caso che ho avuto (in cui la tua risposta ha risolto il mio avvertimento). Basta fare 'dispatch_async (dispatch_get_main_queue(),^(void) { [self.container presentModalViewController: nc animato: YES]; });' che è più semplice e meno hacky. –

+0

Sono totalmente d'accordo con Mark, è più semplice usare solo 'dispatch_async (dispatch_get_main_queue(), {code block}) – Dean

+7

' dispatch_async() 'non funziona su iOS8 per me ma' dispatch_after() 'ha funzionato. Il rovescio della medaglia è che vedo il rootViewController per un momento (a causa del ritardo di 0.1f). – SoftDesigner

10

Ho il sospetto che si stia tentando di chiamare presentModalViewController: prima che la barra delle schede abbia terminato il caricamento. Provare a spostare la logica finale al prossimo ciclo di eventi:

[self.window makeKeyAndVisible]; 
    [self performSelector:(handleLogin) withObject:nil afterDelay:0]; 
} 

- (void)handleLogin 
{ 
    if (![[ZYHttpRequest sharedRequest] userID]) 
    { 
     // should register or login firstly 
     LoginViewController *loginVC = [[LoginViewController alloc] initWithNibName:@"LoginViewController" 
                      bundle:nil]; 
     loginVC.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; 
     [self.tabBarController presentModalViewController:loginVC animated:YES]; 
     ZY_SAFE_RELEASE(loginVC); 
    } 
} 
+0

Ciao Rob, grazie per la tua risposta! Ha risolto il mio problema! – ZYiOS

+0

[self performSelector: (handleLogin) withObject: nil afterDelay: 0.1]; funziona nel mio iPod 4G, se il ritardo è 0, funzionerà solo su simulatore ma riceverai lo stesso avviso nel dispositivo. – ZYiOS

+0

Grazie, grazie, grazie. La risposta selezionata ha la stessa idea, ma molto più complicata, e per me ha funzionato alla grande. –

5
[self.tabBarController presentModalViewController:loginVC animated:**NO**]; 
+0

Questo funziona per me --- +1 –

+0

Funziona alla grande! +1 – Nanego

+4

questa soluzione non è la soluzione. – Karsten

2

ho avuto un problema simile quando t rying to presentModalViewController (my welcome screen) nella vista principaleWillAppear. È stato risolto semplicemente spostando la chiamata VC modale a viewDidAppear.

0
[self performSelector:@selector(modaltheView) withObject:self afterDelay:0.1]; 
-(void)modaltheView 
{ 
    [self.container presentModalViewController:nc animated:YES]; 
} 
Problemi correlati