如何使用UISplitViewController作为模态视图控制器?
我想显示一个UISplitViewController,将它作为模态视图控制器呈现在我的iPad应用程序中。我设法显示它,但由于某种原因,模态视图的左侧与状态栏的大小之间存在差距,当方向改变时它也被保留。如何使用UISplitViewController作为模态视图控制器?
有谁知道为什么发生这种情况?或者如果这甚至是可能的?也许我只是挖掘自己一个巨大的漏洞。
股票UISplitViewController
仅用作根视图控制器。以模态形式呈现模式违反了Apple人机界面准则,并且很有可能被App Review团队拒绝。此外,您可能会收到错误:
Application tried to present Split View Controllers modally
技术上讲,这是我做的:
1 /子类一个UIViewController即。 @interface aVC:UIViewController
2 /在viewDidLoad中,设置一个splitViewController,即。 aSplitVC
3 /然后self.view = aSplitVC.view
毕竟,现在的AVC作为modalViewController
上的Xcode 8不工作,iOS的8+ 有错误日志:“视图一次只能与最多一个视图控制器关联!” – Jerome 2017-09-19 14:04:33
我与埃文同意这是稍微偏离颜色的苹果,但我才得以完成这与以下解决方案的工作版本:
UISplitViewController *splitVC = [[UISplitViewController alloc] init];
splitVC.delegate = VC2;
splitVC.viewControllers = [NSArray arrayWithObjects:navcon1, navcon2, nil];
UINavigationController *splitNavCon = [[UINavigationController alloc] init];
splitNavCon.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[splitNavCon.view addSubview:splitVC.view];
VC2.splitParentViewController = splitNavCon;
[self presentViewController:splitNavCon animated:YES completion:nil];
这让我在这是模式地呈现在屏幕上的新UISplitViewController工作后退按钮。
你会注意到我实际上通过了VC2(UISplitViewController的委托)它的父UINavigationController。这是我发现我可以从VC2内驳回UISplitViewController的最佳方式:
[splitParentViewController dismissViewControllerAnimated:YES completion:nil];
像你们许多人,我需要一个“模式的方式”使用UISplitViewController。这似乎是一个老问题,但我在StackOverflow中发现的所有内容最多只能解释为什么当您尝试这样做时出现问题(如上面所接受的答案)或“黑客入侵”。
但是,有时候改变大部分代码库并使UISplitViewController成为初始对象只是为了使其功能正常运行并不是很方便。
事实证明,有一种方法可以让每个人都感到高兴(包括Apple指南)。我发现最好的解决办法,是正常使用UISplitViewController,但必须要显示/驳回的时候,用下面的办法:
-(void)presentWithMasterViewController: (UIViewController *) thisMasterViewController
andDetailViewController: (UIViewController *) thisDetailViewController
completion:(void(^)(void))completion
{
masterViewController = thisMasterViewController;
detailViewController = thisDetailViewController;
[self setViewControllers:[NSArray arrayWithObjects:masterViewController, detailViewController, nil]];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
self.window.rootViewController = self;
[self.window makeKeyAndVisible];
if(completion)
completion();
}
-(void)dismissViewControllerWithCompletion:(void (^)(void))completion
{
self.window = nil;
masterViewController = nil;
detailViewController = nil;
if(completion)
completion();
}
其中的“窗口”,是您UISplitViewController子类的属性。系统会照顾其余的!
为了方便/参考,我上传这是一个UISplitViewController子类的GitHub:
--EXAMPLE对如何使用 -
mySplitViewController = [[ModalSplitViewController alloc] init];
mySplitViewController.delegate = self;
[mySplitViewController presentWithMasterViewController:masterViewController andDetailViewController:detailViewController completion:nil];
// when done:
[mySplitViewController dismissViewControllerWithCompletion:nil];
mySplitViewController = nil;
侧面说明:我猜大部分的混淆源于以下事实:Apple文档中的UISplitView使用示例使用在AppDelegate中创建的窗口 ,而事实上大多数人不是 对窗口概念非常熟悉 - 因为我们通常不需要 (它们在StoryBoard或样板代码中创建一次)。
此外,如果您正在进行状态恢复,则不应该使用 忘记程序自动创建的UIViewControllers不会自动由系统恢复 。
我相信人们可以用相反的方式:而不是自定义控制器呈现分割控制器,可以将分割控制器设置为故事板中的根窗口控制器,并且在其视图顶部可以添加自定义控制器即登录屏幕),并在需要时将其从屏幕(例如removeFromSuperview)中删除。
这个答案实际上并不正确,因为它自iOS8以后不再有效,如果你需要支持甚至是iOS7,你可以这样做,就像你实际上将模态UIViewController的容器作为SplitView一样。
let mdSplitView = self.storyboard?.instantiateViewControllerWithIdentifier("myDataSplitView") as! MyData_SplitVC
self.addChildViewController(mdSplitView)
mdSplitView.view.bounds = self.view.bounds
self.view.addSubview(mdSplitView.view)
mdSplitView.didMoveToParentViewController(self)
一种替代方法是尝试对大小售后SPLITVIEW控制器,诸如https://github.com/SlavaBushtruk/APSplitViewController – 2013-04-30 08:27:46
upvoted为“售后视图控制器” – 2014-07-25 16:58:23