UITabBarController - 子视图控制器(选项卡)的边界不正确且不一致

8
我有一个带有两个标签的UITabBarController,每个标签都是一个UITableViewController。
当UITabBarController出现时,两个标签视图的边界都不正确。第一个标签在导航栏下方正确地放置,但底部超出了选项卡栏。第二个标签恰好相反,从导航栏下方开始,但在底部选项卡栏前停止。
我按照如下方式创建和呈现TabBarController:
ActiveListTabBarViewController* listTabBarController = [[ActiveListTabBarViewController alloc] initWithListController:_listController];
UINavigationController* nc = [[UINavigationController alloc] initWithRootViewController:listTabBarController];
[self presentViewController:nc animated:YES completion:^(){}];

在TabBarController的init中,按照以下方式创建并添加子视图(选项卡):

_todoListViewController = [[BasicTableViewController alloc] initWithList:[_controller itemsToDo]];
_todoListViewController.delegate = self;
_todoListViewController.title = @"To Do";
_completedListViewController = [[BasicTableViewController alloc] initWithList:[_controller itemsDone]];
_completedListViewController.delegate = self;
_completedListViewController.title = @"Completed";

[self setViewControllers:@[_todoListViewController, _completedListViewController]];

我做错了什么?

谢谢, Gavin

更新:根据添加以下方法的建议,BasicTableViewController

- (UIRectEdge)edgesForExtendedLayout
{
    return UIRectEdgeNone;
}

第一个选项卡的行为已经得到改善并正确地定位,但第二个选项卡仍然保持不变。目前情况如下:
enter image description here
有什么建议吗?谢谢!
2个回答

3
问题是由我呈现UITabBarController的方式引起的。
ActiveListTabBarViewController* listTabBarController = [[ActiveListTabBarViewController alloc] initWithListController:_listController];
UINavigationController* nc = [[UINavigationController alloc] initWithRootViewController:listTabBarController];
[self presentViewController:nc animated:YES completion:^(){}];

回到苹果文档,我不确定这是否是一种有效的方式来呈现UITabBarController。也就是说,将其作为另一个视图控制器的子控制器呈现。

事实并非如此。以下是一些片段,证实了这一点;根据这些以及结果的变化,我认为像上面那样呈现TabBarController是不正确的。

From: https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/ViewControllerCatalog/Chapters/TabBarControllers.html

在创建标签栏界面之前,您需要决定如何使用标签栏界面。因为它会对您的数据进行全局组织,所以您只应按以下特定方式使用:
  • 将其直接安装为窗口的根视图控制器。
  • 将其安装为分割视图界面中的两个视图控制器之一。(仅适用于iPad)
  • 从另一个视图控制器模态呈现它。
  • 从弹出视图中显示它。(仅适用于iPad)

From: https://developer.apple.com/library/ios/documentation/uikit/reference/UITabBarController_Class/Reference/Reference.html

与其他视图控制器不同,选项卡界面不应作为另一个视图控制器的子级安装。
进一步澄清:
选项卡控制器是一个容器视图控制器,用于将您的应用程序分成两个或多个不同的操作模式。
导航控制器呈现按层次结构组织的数据,并是UINavigationController类的实例。该类的方法提供了管理基于堆栈的内容视图控制器集合的支持。
我将UITabBarController作为导航控制器的根视图呈现的原因是,我想要导航栏...
这是我现在在TabBarController的init中实现的方式:
- (id)initWithListController:(BasicListController *)controller
{
    self = [super init];
    if (self) {
        _controller = controller;

        _todoListViewController = [[BasicTableViewController alloc] initWithList:[_controller itemsToDo]];
        _todoListViewController.delegate = self;
        _todoListViewController.title = @"To Do";

        _completedListViewController = [[BasicTableViewController alloc] initWithList:[_controller itemsDone]];
        _completedListViewController.delegate = self;
        _completedListViewController.title = @"Completed";

        UINavigationController* ncTodo = [[UINavigationController alloc] initWithRootViewController:_todoListViewController];
        UINavigationController* ncCompleted = [[UINavigationController alloc] initWithRootViewController:_completedListViewController];

        [self setViewControllers:@[ncTodo, ncCompleted]];

        UIBarButtonItem* doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStylePlain target:self action:@selector(doneTap:)];
        _todoListViewController.navigationItem.leftBarButtonItem = doneButton;
        _completedListViewController.navigationItem.leftBarButtonItem = doneButton;
    }
    return self;
}

注意,我不需要处理以下内容:

  • edgesForExtendedLayout
  • automaticallyAdjustsScrollViewInsets
  • extendedLayoutIncludesOpaqueBars

iOS 7的默认设置会考虑导航栏和标签栏(与上面的原始屏幕截图不同,在那些截图中UITabBarController被错误地呈现)。


1
这非常有帮助。值得更多的点赞!然而,我遇到了按钮有时会消失的问题,所以最终我为每个选项卡创建了每个按钮的新实例,以避免将同一个按钮添加到两个不同的视图中。当你想到它时,也许一个视图不应该是两个其他视图的子视图。 - Thibault D.

2

尝试在您的视图控制器中实现此方法:

- (UIRectEdge) edgesForExtendedLayout
{
    return UIRectEdgeNone;
}

有趣的是,这导致了第一个选项卡的正确边界;现在完全正确,位于 nag 栏和选项卡栏之间。但第二个选项卡没有变化;它仍然放置在导航栏下方,但正确地不会超出选项卡栏。谢谢。 - Gavin Hope

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