如何使用UISplitViewController作为模态视图控制器?

时间:2011-01-19 19:36:58

标签: ipad ios uisplitviewcontroller modalviewcontroller

我正在尝试在我的iPad应用程序中显示一个UISplitViewController,将其显示为模态视图控制器。我设法显示它,但由于某种原因,模态视图左侧有一个间隙,状态栏的大小也会在方向更改时保留。

alt text

有人知道为什么会这样吗?或者如果这是可能的话?也许我只是在挖自己一个巨大的洞。

6 个答案:

答案 0 :(得分:8)

和你们许多人一样,我需要一种'模态方式'来使用UISplitViewController。这似乎是一个老问题,但我在StackOverflow中发现的最多只是解释为什么当你试图这样做时(例如上面接受的答案)或'hack-arounds'时问题发生。

但是,有时更改大部分代码库并使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();
 }

where“window”,是UISplitViewController子类的属性。系统将负责其余部分!

为了方便/参考,我将它作为UISplitViewController子类上传到gitHub:

ModalSplitViewController

- 如何使用示例 -

    mySplitViewController = [[ModalSplitViewController alloc] init];
    mySplitViewController.delegate = self;

    [mySplitViewController presentWithMasterViewController:masterViewController andDetailViewController:detailViewController completion:nil];

    // when done:

    [mySplitViewController dismissViewControllerWithCompletion:nil];
    mySplitViewController = nil;

旁注:我猜大多数混乱源于这样的事实 Apple文档中的UISplitView用法示例使用该窗口 在appDelegate中创建,并且大多数人都没有 熟悉窗口概念 - 因为我们通常不需要 to(它们在StoryBoards或样板代码中创建一次)。

此外,如果您正在进行状态恢复,则不应该 忘记以编程方式创建的UIViewControllers不会 由系统自动恢复。

答案 1 :(得分:6)

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

  

应用程序尝试以模态方式显示拆分视图控制器

答案 2 :(得分:3)

从技术上讲,这就是我所做的:

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

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

3 /然后self.view = aSplitVC.view

毕竟,将aVC呈现为modalViewController

答案 3 :(得分:3)

我同意Evan的说法,这对Apple来说略显偏色,但我能够通过以下解决方案完成此版本的工作:

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

答案 4 :(得分:0)

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

答案 5 :(得分: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)