带有故事板的 UISplitViewController 中的 UITabBarController

UITabBarController in UISplitViewController with Storyboard

我有 UISplitViewControllerUITabBarController 是它的主人。 UITabBarController 包含一个 UINavigationControllerUITableViewController 作为其根(它是我的应用程序的 主菜单 )。

主菜单 中点击任何单元格后,在 UISplitViewController 的详细信息部分应该会显示另一个 UITableViewController(我们称它为 详细视图).

在横向模式下一切正常。

但是在纵向模式下,当我点击 主菜单 中的单元格时, 详细视图 会以模态方式呈现,而不是被推送,例如它应该。此外,当从横向旋转到纵向时,会显示 主菜单 而不是 详细视图 ,在我单击 主菜单之后菜单 显示详细视图 的位置,它以模态方式呈现,无法旋转或返回。

删除 UITabBarController 并将 UINavigationController 设置为 UISplitViewController 的主控工作如我所愿(在横向模式下我们有 menu|细节 并排视图和纵向模式控制器的行为与常规视图一样 UINavigationController)。但是 UITabBarController 不见了。

我试过的:

我想要的是完全在 Storyboard 中完成(好吧,自定义 segues 不算数)- 我想要一个优雅的解决方案,但我拒绝相信这是不可能的。

正在开发 iOS 8 SDK,Xcode 6.2,iPhone 6 Plus

不幸的是,没有绝对优雅的解决方案(据我设法完成)。希望 Apple 最终会解决这个问题,但与此同时,这是 可能的最佳方式:

  • 放置一个自定义 segue 而不是 显示详细信息
  • 在您的自定义 segue 的 perform 方法中有类似的内容:
- (void)perform
{
    MasterViewController *source = self.sourceViewController;

    AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
    UISplitViewController *splitViewController = appDelegate.splitViewController;
    if ([splitViewController.viewControllers count] > 1) {
        [source performSegueWithIdentifier:@"showDetail" sender:source];
        if (appDelegate.masterPopoverController) {
            [appDelegate.masterPopoverController dismissPopoverAnimated:YES];
        }
    } else {
        [source performSegueWithIdentifier:@"showDetailSmallDevice" sender:source];
    }
}
  • [splitViewController.viewControllers count] 在这里只是为了将 large 设备(iPad 和 iPhone 6 Plus)和另一个 smaller
  • 在你的 Storyboard 中,连接一个名为 showDetail 的 segue,它实际上是一个 showDetail,到细节导航控制器, 并直接到内容视图控制器另一个 showDetailSmallDevice 实际上是 Show (推)

看例子:

http://i.stack.imgur.com/GQpg3.png

编辑: SplitViewController 需要两个导航控制器。解决方法是在SplitViewControllerDatailViewController之间再插入一个Navigation Controller。然后,从 TableView 直接执行一个 Segue 到第二个 Navigation Controller。 SplitViewControllers 想要两个导航控制器...

也许一个好方法是在 IB 上开始一个新的 SplitViewController 项目。有多种默认方法和属性来管理 SplitViewController。你可以在 appDelegate class 中找到一些东西,它可能是一个很好的起点。

OLD:我喜欢 Mateusz 的回答,这只是一个可以使用 self.splitViewController.isCollapsed 来测试 DetailViewController 是否显示在屏幕上的要点。有了这个 属性 就不需要计算 viewControllers 了。

@property(nonatomic, readonly, getter=isCollapsed) BOOL collapsed

来自文档:一个布尔值,指示是否仅显示一个子视图控制器。当拆分视图控制器内容在语义上折叠到单个容器中时,此 属性 设置为 YES。当拆分视图控制器从水平常规环境过渡到水平紧凑环境时,就会发生折叠。折叠后,拆分视图控制器报告其视图控制器中只有一个子视图控制器属性。