在iOS8中使用UISplitViewController隐藏主视图控制器
我有一个iOS7应用程序,它基于Xcode主细节模板,我正在移植到iOS8。  UISplitViewController是一个变化很大的UISplitViewController 。 
在纵向模式下时,如果用户点击详细视图控制器,主视图控制器将被解除:

我也想能够以编程方式隐藏主视图控制器,如果用户轻击一行。
在iOS 7中,主视图控制器显示为popup式窗口,可以隐藏,如下所示:
 [self.masterPopoverController dismissPopoverAnimated:YES]; 
随着iOS 8,主人不再是一个popup窗口,所以上述技术将无法正常工作。
我试图解雇主视图控制器:
 self.dismissViewControllerAnimated(true, completion: nil) 
或者告诉分割视图控制器显示细节视图控制器:
 self.splitViewController?.showDetailViewController(bookViewController!, sender: self) 
但到目前为止没有任何工作。 有任何想法吗?
按如下方式扩展UISplitViewController:
 extension UISplitViewController { func toggleMasterView() { let barButtonItem = self.displayModeButtonItem() UIApplication.sharedApplication().sendAction(barButtonItem.action, to: barButtonItem.target, from: nil, forEvent: nil) } } 
 在didSelectRowAtIndexPath或prepareForSegue ,执行以下操作: 
 self.splitViewController?.toggleMasterView() 
这将顺利地滑动主视图。
我从这篇文章中得到了使用displayModeButtonItem()的想法,并且我正在模拟在这篇文章中点击它。
我对这个解决scheme并不满意,因为它看起来像一个黑客。 但它运作良好,似乎没有其他select。
 通过在MasterViewController的- prepareForSegue:sender:方法中添加以下代码,我能够在Xcode 6.3主 – 细节应用程序(通用)项目中获得所需的行为: 
 if view.traitCollection.userInterfaceIdiom == .Pad && splitViewController?.displayMode == .PrimaryOverlay { let animations: () -> Void = { self.splitViewController?.preferredDisplayMode = .PrimaryHidden } let completion: Bool -> Void = { _ in self.splitViewController?.preferredDisplayMode = .Automatic } UIView.animateWithDuration(0.3, animations: animations, completion: completion) } 
  complete - prepareForSegue:sender:实现应该如下所示: 
 override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if segue.identifier == "showDetail" { if let indexPath = self.tableView.indexPathForSelectedRow() { let object = objects[indexPath.row] as! NSDate let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController controller.detailItem = object controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem() controller.navigationItem.leftItemsSupplementBackButton = true if view.traitCollection.userInterfaceIdiom == .Pad && splitViewController?.displayMode == .PrimaryOverlay { let animations: () -> Void = { self.splitViewController?.preferredDisplayMode = .PrimaryHidden } let completion: Bool -> Void = { _ in self.splitViewController?.preferredDisplayMode = .Automatic } UIView.animateWithDuration(0.3, animations: animations, completion: completion) } } } } 
 在某些项目中,使用traitCollection也可能是displayMode的替代/补充。 例如,以下代码也适用于Xcode 6.3主/从应用程序(通用)项目 : 
 let traits = view.traitCollection if traits.userInterfaceIdiom == .Pad && traits.horizontalSizeClass == .Regular { let animations: () -> Void = { self.splitViewController?.preferredDisplayMode = .PrimaryHidden } let completion: Bool -> Void = { _ in self.splitViewController?.preferredDisplayMode = .Automatic } UIView.animateWithDuration(0.3, animations: animations, completion: completion) } 
 使用preferredDisplayMode 。 在didSelectRowAtIndexPath或prepareForSegue : 
 self.splitViewController?.preferredDisplayMode = .PrimaryHidden self.splitViewController?.preferredDisplayMode = .Automatic 
不幸的是,主视图突然消失,而不是滑开,尽pipe文档说明:
如果更改此属性的值会导致当前显示模式的实际更改,则分割视图控制器会animation生成的更改。
希望有一个更好的方法来实现这个变化。
下面的代码用animation隐藏主视图
 UIView.animateWithDuration(0.5) { () -> Void in self.splitViewController?.preferredDisplayMode = .PrimaryHidden } 
只是稍微改进了一下这里列出的答案,下面的代码对我来说是正常工作的,它也能顺利地处理animation:
 extension UISplitViewController { func toggleMasterView() { var nextDisplayMode: UISplitViewControllerDisplayMode switch(self.preferredDisplayMode){ case .PrimaryHidden: nextDisplayMode = .AllVisible default: nextDisplayMode = .PrimaryHidden } UIView.animateWithDuration(0.5) { () -> Void in self.preferredDisplayMode = nextDisplayMode } } } 
然后,如前所述,您只需在视图控制器中的任意位置使用扩展function
 self.splitViewController?.toggleMasterView() 
修改上面的答案是我configuration视图的详细视图控制器的一个方法所需要的:
  [self.splitViewController setPreferredDisplayMode:UISplitViewControllerDisplayModePrimaryHidden]; 
当然,它缺乏animation的优雅。
我在Swift 1.2中的解决scheme
  override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){ var screen = UIScreen.mainScreen().currentMode?.size.height if (UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad) || screen >= 2000 && UIDevice.currentDevice().orientation.isLandscape == true && (UIDevice.currentDevice().userInterfaceIdiom == .Phone){ performSegueWithIdentifier("showDetailParse", sender: nil) self.splitViewController?.preferredDisplayMode = UISplitViewControllerDisplayMode.PrimaryHidden } else if (UIDevice.currentDevice().userInterfaceIdiom == .Phone) { performSegueWithIdentifier("showParse", sender: nil) } } 
为iPad添加像这样的菜单button
 UIBarButtonItem *menuButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"burger_menu"] style:UIBarButtonItemStylePlain target:self.splitViewController.displayModeButtonItem.target action:self.splitViewController.displayModeButtonItem.action]; [self.navigationItem setLeftBarButtonItem:menuButtonItem]; 
这项工作与横向和纵向模式很好。 以编程方式closurespopupvc你只需要强制button这样的行动
 [self.splitViewController.displayModeButtonItem.target performSelector:appDelegate.splitViewController.displayModeButtonItem.action]; 
尝试
让svc = self.splitViewController svc.preferredDisplayMode = UISplitViewControllerDisplayMode.PrimaryHidden