【问题标题】:How to present a TabBarController modal如何呈现 TabBarController 模式
【发布时间】:2014-01-14 09:21:36
【问题描述】:

从一个视图(LoginTesteInicial)我可以转到两个 tabBarControllers,但是当我运行代码时,它会因以下错误而崩溃: Attempt to present <UITabBarController: 0x8a4a870> on <LoginTesteInicial: 0x8a46970> whose view is not in the window hierarchy!

这是我来自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];

【问题讨论】:

  • 你是在 viewDidLoad 中调用它吗?

标签: ios viewcontroller tabbar


【解决方案1】:

您的问题的答案是,当调用-viewDidLoad 时,视图控制器的视图不在视图层次结构中。您需要等到视图被放入视图层次结构中。这可以在-viewWillAppear:-viewDidAppear: 中完成。


您收到“开始/结束外观转换的不平衡调用”警告是因为视图控制器在被另一个视图控制器替换之前尚未完全加载。为避免该警告,您可以使用-performSelector:withObject:afterDelay: 将当前视图控制器安排在下一个运行循环中。

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

【讨论】:

  • 这是有效的,但只出现 TabBarController 的第一个选项卡。 TabBar 只有第一个选项卡项。
  • @GabrielMolter 我不知道。这将是一个更深入的了解,以了解您的故事板发生了什么,它是如何加载的,......您可能想将其作为一个单独的问题发布。
【解决方案2】:

将 [self presentViewController:vc animated:YES completion:nil] 和相关代码移动到其中一个

1 viewWillAppear

2viewWillLayoutSubviews

3viewDidLayoutSubviews

您需要保留一个标志,以确保即使其中一种方法多次触发,您的视图也只会呈现一次。

或者您可以避免呈现视图并添加为子视图,如果您不喜欢保留标志等,请执行此操作而不是呈现。

[self.view addSubview:vc.view];

[self addChildViewController:vc];

[vc didMoveToParentViewController:self] 

【讨论】:

  • 它有效,但出现了:对 的开始/结束外观转换的不平衡调用。
  • 保留一个标志,它会跟踪它是否出现,如果已经出现,则不再显示
  • 声明标志 BOOL isAlreadyDisplayed 在你的班级。使用 if(isAlreadyDisplayed){ [self presentViewController:vc animated:YES completion:nil]; }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 2016-11-14
  • 2020-06-29
  • 1970-01-01
相关资源
最近更新 更多