Несбалансированные вызовы для начала/завершения переходов внешнего вида для UITabBarController

У меня есть 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;
}

Любой, кто может мне помочь? Заранее спасибо!


person ZYiOS    schedule 19.12.2011    source источник
comment
Кроме того, я проверил это [stackoverflow.com/q/7886096/527539]. Но не повезло.   -  person ZYiOS    schedule 19.12.2011


Ответы (3)


Вам нужно подождать, чтобы представить контроллер модального представления до следующего цикла выполнения. В итоге я использовал блок (для упрощения), чтобы запланировать презентацию для следующего цикла выполнения:

Обновление:
Как отметил Марк Амери ниже, работает простое 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];
});
person Maurizio    schedule 27.12.2011
comment
Здесь нет необходимости в таймере, по крайней мере, в моем случае (в котором ваш ответ разрешил мое предупреждение). Просто сделайте dispatch_async(dispatch_get_main_queue(), ^(void){ [self.container presentModalViewController:nc animated:YES]; });, что проще и менее хакерски. - person Mark Amery; 18.09.2013
comment
Я полностью согласен с Марком, проще использовать `dispatch_async(dispatch_get_main_queue(), {блок кода}) - person Dean; 25.07.2014
comment
dispatch_async() у меня не работало на iOS8, но dispatch_after() работало. Недостатком этого является то, что я на мгновение вижу rootViewController (из-за задержки 0,1f). - person SoftDesigner; 22.09.2014
comment
@SoftDesigner У меня та же проблема, на мгновение отображается rootViewController. Вы нашли решение этой проблемы? - person entropid; 17.10.2014
comment
@Entropid нет, мне пришлось изменить структуру контроллеров представления, чтобы избежать этого. - person SoftDesigner; 17.10.2014
comment
Я использую [[NSRunLoop currentRunLoop] runUntilDate: [дата NSDate]]; перед PresentViewController:, мне кажется, это лучше, так как вы уверены, что этот цикл выполнялся до представления. - person Povilas; 17.12.2014
comment
@Entropid на iOS8 Мне пришлось отложить первую презентацию до viewDidAppear на корневом контроллере представления (который должен быть загружен к этому моменту). К сожалению, есть небольшая задержка и, увы, viewWillAppear слишком рано. - person wcochran; 15.07.2015

Я подозреваю, что проблема в том, что вы пытаетесь вызвать 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);
    }
}
person Rob Napier    schedule 21.12.2011
comment
[самостоятельный селектор: (handleLogin) withObject: nil afterDelay: 0.1]; работать в моем iPod 4G, если время задержки равно 0, будет работать только на симуляторе, но получить такое же предупреждение на устройстве. - person ZYiOS; 28.12.2011
comment
Спасибо Спасибо спасибо. Выбранный ответ имеет ту же идею, но намного сложнее, и это отлично сработало для меня. - person Le Mot Juiced; 21.07.2013

У меня была аналогичная проблема, когда я пытался представить ModalViewController (мой экран приветствия) в главном представлении viewWillAppear. Это было решено простым переносом модального вызова VC на viewDidAppear.

person Arseniy    schedule 09.11.2012