Question

From one view(LoginTesteInicial) I can go to two tabBarControllers, but when I run the code, it crashes with this error: Attempt to present <UITabBarController: 0x8a4a870> on <LoginTesteInicial: 0x8a46970> whose view is not in the window hierarchy!

here is my code from LoginTesteInicial.m:

UITabBarController *vc;

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {

    vc = [[UIStoryboard storyboardWithName:@"Main_iPad" bundle:nil] instantiateViewControllerWithIdentifier:@"TabBarSemLogin"];
} else {

    vc = [[UIStoryboard storyboardWithName:@"Main_iPhone" bundle:nil] instantiateViewControllerWithIdentifier:@"TabBarSemLogin"];
}

[vc setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];

[self presentViewController:vc animated:YES completion:nil];
Was it helpful?

Solution

The answer to your question is that when -viewDidLoad is called, the view controller's view is not in the view hierarchy. You need to wait until the view is placed into the view hierarchy. This can been done either in -viewWillAppear: or -viewDidAppear:.


The "Unbalanced calls to begin/end appearance transitions" warning you get is because a view controller has not be fully loaded before being replaced with another view controller. To avoid that warning, you can use -performSelector:withObject:afterDelay: to schedule the present view controller in the next run loop.

- (void)viewDidAppear:(BOOL)animated
{
    …
    [self performSelector:@selector(showTabBarController) withObject:nil afterDelay:0.0];
}

- (void)showTabBarController
{
    UITabBarController *vc;
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        vc = [[UIStoryboard storyboardWithName:@"Main_iPad" bundle:nil] instantiateViewControllerWithIdentifier:@"TabBarSemLogin"];
    } else {
        vc = [[UIStoryboard storyboardWithName:@"Main_iPhone" bundle:nil] instantiateViewControllerWithIdentifier:@"TabBarSemLogin"];
    }

    [vc setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
    [self presentViewController:vc animated:YES completion:nil];
}

OTHER TIPS

Move [self presentViewController:vc animated:YES completion:nil] and related code it either of these

1 viewWillAppear

2 viewWillLayoutSubviews

3 viewDidLayoutSubviews

You will need to keep one flag which will take care that even if one of these method triggered multiple times your view will get presented only once.

Or you can avoid presenting view and add as subview, do this instead of presenting if you didn't like keeping flag etc.

[self.view addSubview:vc.view];

[self addChildViewController:vc];

[vc didMoveToParentViewController:self] 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top