显示详细视图控制器时,iOS8 UIToolbar消失

时间:2014-10-13 18:31:36

标签: storyboard ios8 uisplitviewcontroller uitoolbar

我正在使用UISplitViewController作为窗口的根目录使用应用。我希望主视图控制器和详细视图控制器都是UITableViewController内的UINavigationControllerUIToolbar可见。在水平常规尺寸宽度,这工作正常,如下所示:

iPad 2

问题出现在一个水平紧凑的大小类中,UISplitViewController将详细视图控制器推到像UINavigationController这样的堆栈上,工具栏在显示细节时消失,并在之后重新出现细节完全弹出(见下文)。我希望工具栏能够保持原样,就像使用普通的导航控制器一样。

enter image description here

示例项目已上传here

2 个答案:

答案 0 :(得分:6)

对于这个初始实现,我认为Apple选择隐藏主工具栏,因为(主)导航控制器不能使用单个工具栏同时在屏幕上,并且滑动(不同的项目)在屏幕上。如果您查看Apple的邮件应用程序,他们的主工具栏会在推送动画期间消失,就像您正在看到的那样。

有趣的是,他们的日历应用程序在白天和事件视图控制器转换之间使用了一个非常好的工具栏crossFade。如果您查看该动画,您可以看到它是两个视图的单个工具栏,而不是在第一个动画上方设置动画的第二个工具栏。

尽管UINavigationController私密支持crossFade,但Apple并未针对此特定视图控制器动画启用它。 _shouldCrossFadeBottomBars返回NO,并且delegateShouldCrossFadeBottomBars导航控制器标志没有设置器。

我提交了一个错误报告以及一个增强请求,以支持统一故事板UISplitViewController的底栏动画。我相信Apple会改进iPhone的分割视图控制器功能。

与此同时,您可以通过隐藏主导航控制器的工具栏来处理此问题,并将工具栏添加到主视图控制器的故事板中。这将允许主视图控制器自己的工具栏在屏幕上,而详细视图控制器的工具栏项目可以滑入。

这将涉及将您的主人UITableViewController更改为UIViewController。添加UIToolbar和约束。对于该表,您可以放入UITableView,或使用容器视图并将其连接到UITableviewController

DetailViewController中设置详细信息视图工具栏。

- (void)viewDidLoad {
    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

    UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] init ...];
    self.toolbarItems = @[barButtonItem];

    [self configureView];
}

导航控制器将在视图出现之前设置工具栏项(在视图加载之后),并且工具栏将与详细视图一起推到屏幕上。

如果您有点好奇,请按照我的理解,使用水平紧凑尺寸类的详细视图工具栏。它是辅助导航控制器,细节视图控制器,被推送到主导航控制器堆栈。主导航控制器从辅助导航控制器中获取其装饰,以及属于其可见(详细)视图控制器的navigationItems(和toolbarItems)。

不幸的是,幕后崩溃拆分视图的辅助(导航)控制器会影响您的工具栏,因为主导航控制器接管了辅助导航控制器正在处理的内容。

我们所做的只是将辅助工具栏从辅助导航控制器移动到详细视图控制器,因此主导航控制器可以在辅助导航控制器被推动时处理详细视图控制器的工具栏动画

也许在未来的更新中,拆分视图控制器将能够为故事板的工具栏设置动画,但就目前而言,我知道如何操作的唯一方法是使用代码。

答案 1 :(得分:3)

如果您需要在不更改默认视图控制器的情况下使用主 - 细节应用程序,并且在按下详细视图控制器时工具栏消失,您可以将以下代码行添加到主视图控制器在viewWillAppear中,当它弹出时,工具栏在segue期间存在,而不是等到segue完成后才出现。

self.navigationController?.setToolbarHidden(false, animated: true)

当然,您可以删除默认的表视图控制器并使用带有表格视图的标准视图控制器并添加工具栏,然后您就不会遇到此问题。它确实打破了一行代码,因为它不再位于表视图控制器中,标准导航控制器也不支持clearsSelectionOnViewWillAppear。

tableView.clearsSelectionOnViewWillAppear = self.splitViewController!.collapsed

您可以通过将此代码添加到viewWillAppear ...

来解决此问题
        if let indexPath = tableView.indexPathForSelectedRow {
        tableView.deselectRowAtIndexPath(indexPath, animated: true)
    }