UITabBarController的出现和消失转换调用不平衡

28

我有一个UITabBarController,在初始运行时,我想叠加一个登录视图控制器,但收到了错误信息。

对于 <UITabBarController:0x863ae00>,开始/结束外观转换的调用不平衡。

下面是代码。

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

有谁能帮助我吗?提前感谢您!


另外,我已经检查了这个[https://dev59.com/Omsz5IYBdhLWcg3wcnhb]。但是没有运气。 - ZYiOS
5个回答

78

你需要等待到下一个运行循环来呈现模态视图控制器。最终我使用了一个块(使事情更加简单)来安排在下一个运行循环中呈现:

更新:
如下面的 Mark Amery 所提到的,只需要一个简单的dispatch_async就可以完成,不需要计时器:

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
在这种情况下(你的答案解决了我的警告),不需要使用定时器,只需执行以下操作:dispatch_async(dispatch_get_main_queue(), ^(void){ [self.container presentModalViewController:nc animated:YES]; });这样更简单,也更少使用hacky方法。 - Mark Amery
7
dispatch_async() 在我的iOS8上无法工作,但dispatch_after()可以。不足之处在于我可以看到根视图控制器一瞬间(因为有0.1秒的延迟)。 - SoftDesigner
@SoftDesigner 我也遇到了同样的问题,rootViewController 会短暂地显示。你找到解决方法了吗? - entropid
1
我在调用presentViewController:之前使用[[NSRunLoop currentRunLoop] runUntilDate:[NSDate date]],这样看起来更好,因为你可以确保循环在呈现之前运行。 - Povilas
在iOS8上,对于@Entropid,我必须延迟第一次演示到根视图控制器的viewDidAppear(该点必须通过加载完成)。不幸的是,有一个短暂的延迟,而viewWillAppear则太早了。 - wcochran
显示剩余2条评论

10

我怀疑问题在于你试图在标签栏完成加载之前调用presentModalViewController:。尝试将最终逻辑移动到下一个事件循环中:

  [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,则[self performSelector:(handleLogin)withObject:nil afterDelay:0.1];可以在模拟器中工作,但在我的iPod 4G设备上会收到相同的警告。 - ZYiOS
谢谢你,谢谢你,谢谢你。选定的答案有相同的想法,但更复杂,而这个对我很有效。 - Le Mot Juiced

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

2

当我尝试在主视图的viewWillAppear中展示模态视图控制器(我的欢迎屏幕)时,遇到了类似的问题。只需将模态VC调用移动到viewDidAppear中即可解决。


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接