在iOS8中使用UISplitViewController隐藏主视图控制器
我有一个基于Xcode主/从模板的iOS7应用程序,我将它移植到iOS8。一个变化很大的领域是UISplitViewController
。在iOS8中使用UISplitViewController隐藏主视图控制器
当在纵向模式下,如果用户轻击细节视图控制器上,主视图控制器被驳回:
我还希望能够以编程隐藏如果主视图控制器用户点击一行。
在iOS系统7中,主视图控制器被显示为酥料饼,并且可以隐藏如下:
[self.masterPopoverController dismissPopoverAnimated:YES];
与iOS 8,主不再是酥料饼,因此上述技术不管用。
我试图解雇主视图控制器:
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()
这将主视图平滑地滑动的方式进行。
我得到了从this post使用displayModeButtonItem()的想法,并且我正在模拟点击它,每this post。
我对这个解决方案并不满意,因为它看起来像一个黑客。但它运作良好,似乎没有其他选择。
不错的解决方案。我刚刚测试过它,它按预期工作,在iPad肖像模式下动画制作弹出窗口。唯一的一个副作用就是在iPhone 6+横向模式(而不是iPad)上隐藏主视图 - 另一种iPhone 6+既不是手机也不是平板电脑的欢快方式! – pjh68 2015-01-11 21:35:09
我最终实现了iPhone 6 Plus的设备专用旁路 - 请参阅http://*.com/questions/25780283/ios-how-to-detect-iphone-6-plus-iphone-6-iphone-5-by - 宏检测这种简单的方法。 – pjh68 2015-01-11 21:45:50
嘿非常好的答案,它的作品,但我有另一个问题。它也动画细节视图控制器的变化。这也发生在你身上吗?谢谢 – Sanandrea 2015-02-20 21:08:55
使用preferredDisplayMode
。在didSelectRowAtIndexPath
或prepareForSegue
:
self.splitViewController?.preferredDisplayMode = .PrimaryHidden
self.splitViewController?.preferredDisplayMode = .Automatic
不幸的是,主视图突然消失,而不是滑开,尽管文件指出:
如果更改此属性的值导致的实际变化在 当前显示模式下,分屏视图控制器会动画产生更改的 。
希望有一个更好的方法来做到这一点,实际上是动画变化。
这根本不起作用。在选择了一行后,主视图会保留在屏幕上,并且不会在横向模式下并排显示。 – phatmann 2014-12-10 09:42:26
@phatmann它的工作,我想在我的didSelectRowAtIndexPath方法添加以下代码: - (空)的tableView:(UITableView的*)的tableView didSelectRowAtIndexPath方法:(NSIndexPath *)indexPath { self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryHidden; } – 2014-12-10 10:12:28
如果我把上面的代码放在'prepareForSegue'中,主视图确实消失了。之后我还必须调用'preferredDisplayMode = .Automatic',这样横向操作才是正确的。问题在于主视图不能平滑滑落,使得这种技术不够理想。另一方面,没有人提供了更好的答案,所以谢谢! – phatmann 2014-12-10 10:34:10
我能够在Xcode 6中获得所需的行为。3主从应用程序(通用)项目由MasterViewController
的- prepareForSegue:sender:
方法添加以下代码:
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)
}
完整- 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)
}
卓越的解决方案 – AlexD 2015-07-30 05:43:46
我在夫特1.2
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)
}
}
溶液下面的代码隐藏在主视图与动画
UIView.animateWithDuration(0.5) {() -> Void in
self.splitViewController?.preferredDisplayMode = .PrimaryHidden
}
简单和工作的iOS 10,斯威夫特3.0 – 2017-03-29 09:11:45
@ jithinroy这工作!我一直坚持这个天感谢! – 2017-06-17 21:27:15
只是改善一点点在这里列出的答案已经在这里,下面的代码对我来说工作正常,我t结合处理动画顺利:
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
}
}
}
然后,如前所述,你只需要使用扩展功能在您的视图控制器的任何地方
self.splitViewController?.toggleMasterView()
为iPad添加菜单按钮,这样
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];
这项工作与横向和纵向模式很好。 要以编程方式关闭酥料饼的VC,你只需要迫使这样
[self.splitViewController.displayModeButtonItem.target performSelector:appDelegate.splitViewController.displayModeButtonItem.action];
修改上面这个问题的答案的按钮动作时,所有我需要的是配置的视图我的详细视图控制器的方法:
[self.splitViewController setPreferredDisplayMode:UISplitViewControllerDisplayModePrimaryHidden];
当然,它缺乏动画的优雅。
尝试
let svc = self.splitViewController svc.preferredDisplayMode = UISplitViewControllerDisplayMode.PrimaryHidden
可以请你接受下面的答案吗? – phatmann 2015-01-14 15:08:50