2011-01-19 57 views
6

我想显示一个UISplitViewController,将它作为模态视图控制器呈现在我的iPad应用程序中。我设法显示它,但由于某种原因,模态视图的左侧与状态栏的大小之间存在差距,当方向改变时它也被保留。如何使用UISplitViewController作为模态视图控制器?

alt text

有谁知道为什么发生这种情况?或者如果这甚至是可能的?也许我只是挖掘自己一个巨大的漏洞。

回答

6

股票UISplitViewController仅用作根视图控制器。以模态形式呈现模式违反了Apple人机界面准则,并且很有可能被App Review团队拒绝。此外,您可能会收到错误:

Application tried to present Split View Controllers modally

+2

一种替代方法是尝试对大小售后SPLITVIEW控制器,诸如https://github.com/SlavaBushtruk/APSplitViewController – 2013-04-30 08:27:46

+1

upvoted为“售后视图控制器” – 2014-07-25 16:58:23

3

技术上讲,这是我做的:

1 /子类一个UIViewController即。 @interface aVC:UIViewController

2 /在viewDidLoad中,设置一个splitViewController,即。 aSplitVC

3 /然后self.view = aSplitVC.view

毕竟,现在的AVC作为modalViewController

+0

上的Xcode 8不工作,iOS的8+ 有错误日志:“视图一次只能与最多一个视图控制器关联!” – Jerome 2017-09-19 14:04:33

3

我与埃文同意这是稍微偏离颜色的苹果,但我才得以完成这与以下解决方案的工作版本:

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]; 
8

像你们许多人,我需要一个“模式的方式”使用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:

ModalSplitViewController

--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不会自动由系统恢复 。

0

我相信人们可以用相反的方式:而不是自定义控制器呈现分割控制器,可以将分割控制器设置为故事板中的根窗口控制器,并且在其视图顶部可以添加自定义控制器即登录屏幕),并在需要时将其从屏幕(例如removeFromSuperview)中删除。

0

这个答案实际上并不正确,因为它自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) 
相关问题