2011-12-19 6 views
26

Tengo un UITabBarController, cuando se ejecuta por primera vez, quiero superponer un controlador de vista de inicio de sesión pero recibí el error.Llamadas no balanceadas para comenzar/finalizar transiciones de apariencia para UITabBarController

Llamadas no balanceadas para comenzar/finalizar transiciones de aparición para < UITabBarControlador: 0x863ae00>.

A continuación se muestra el código.

- (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; 
} 

¿Alguien que me puede ayudar? ¡Gracias por adelantado!

+0

Además, he comprobado esto [http://stackoverflow.com/q/7886096/527539]. Pero sin suerte. – ZYiOS

Respuesta

76

hay que esperar para presentar el controlador de vista modal hasta el siguiente bucle de ejecución. Terminé usando un bloque (para hacer las cosas más simples) para programar la presentación de la siguiente ejecución del bucle:

Actualización:
Como se ha mencionado por Mark Amery a continuación, a simples dispatch_async obras, no hay necesidad de un temporizador:

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

No necesito un temporizador aquí, al menos en el caso que tuve (en el cual su respuesta resolvió mi advertencia). Sólo hacer 'dispatch_async (dispatch_get_main_queue(),^(void) { [presentModalViewController self.container: nc animada: SÍ]; });' que es más simple y menos hacky. –

+0

Estoy totalmente de acuerdo con Mark, es más fácil usar 'dispatch_async (dispatch_get_main_queue(), {code block}) – Dean

+7

' dispatch_async() 'no funcionó en iOS8 pero el' dispatch_after() 'funcionó. La desventaja de esto es que veo el RootViewController por un momento (debido a la demora de 0.1f). – SoftDesigner

10

Sospecho que el problema es que está tratando de llamar al presentModalViewController: antes de que la barra de pestañas termine de cargarse. Trate de mover la lógica definitiva al siguiente ciclo de eventos:

[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

Hola Rob, gracias por tu respuesta! ¡Solucionó mi problema! – ZYiOS

+0

[self performSelector: (handleLogin) withObject: nil afterDelay: 0.1]; trabajo en mi iPod 4G, si el tiempo de demora es 0, solo funcionará en el simulador pero recibirá la misma advertencia en el dispositivo. – ZYiOS

+0

Gracias, gracias, gracias. La respuesta seleccionada tiene la misma idea, pero mucho más complicada, y esto funcionó muy bien para mí. –

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

Esto funciona para mí --- +1 –

+0

¡Funciona muy bien! +1 – Nanego

+4

esta solución no es la solución. – Karsten

2

he tenido un problema similar cuando t ried a presentModalViewController (mi pantalla de bienvenida) en la vista principalWillAppear. Se resolvió simplemente moviendo la llamada modal de VC a viewDidAppear.

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