应用程序试图以模态方式呈现拆分视图控制器

7

我仍在努力寻找一种解决方法,理论上这是一个非常简单的任务,即从UIViewController转到Split View Controller。(为什么苹果把它做得这么困难呢)。

我现在处于这样一个阶段:将SplitViewController放入它自己的故事板中。当用户在单个UIView控制器上选择一个按钮时,我调用以下代码:

UISplitViewController *splitVC = [[UIStoryboard storyboardWithName:@"SplitStoryBoard" bundle:nil] instantiateViewController];
    [self presentViewController:splitVC animated:YES completion:nil];

我希望能够加载带有分屏视图控制器的故事板。 但这会导致崩溃,显示“应用程序试图以模态方式呈现分屏视图控制器”。

我在代码中没有指定任何“模态”操作。

是否有解决方法?

5个回答

3
UISplitViewController 必须始终作为根视图控制器,不能以模态方式呈现。请参阅 Apple 文档,其中写道:

分割视图控制器必须始终是您创建的任何界面的根。换句话说,您必须始终将来自 UISplitViewController 对象的视图安装为应用程序窗口的根视图。然后,您可以在分割视图界面的窗格中包含导航控制器、选项卡栏控制器或任何其他类型的视图控制器,以实现您的界面。分割视图控制器无法以模态方式呈现。


1
我可以将SplitViewController嵌入到TabViewController中,并转换到TabViewController。为什么苹果要这样大费周折呢? - drlobo
我不知道,但他们是实现所有这些东西的人... 如果你不遵循他们的建议和规则,迟早会陷入麻烦。 - neutrino
苹果或其他人是否提供了一种模式或想法,以在到达分割视图之前呈现视图?即登录是一个相当常见的场景。一个人如何呈现常规的登录视图,并在登录后转换为分割视图控制器?同样,如果苹果希望成为应用程序的根视图控制器,那么违反这一点或绕过这一点可能不是一个好主意。 - lostintranslation
自从iOS 8以后,这个说法已经不再正确了。 - codingrhythm
即使在iOS7中也不是这样的。你可以以模态方式呈现splitView,但是你需要在iOS7中特别在awakeFromNib中将splitView rootController设置为Alex所说的那样。在iOS8中则不需要。 - Vanya

2

您可以将splitViewController作为TabViewController的视图,但是splitViewController不能以传统意义上的模态控制器的形式存在。要从UIViewController过渡到SplitViewController,请使用以下代码:

- (IBAction)setupTapped:(id)sender {
    static NSString *tabViewControllerIdentifier = @"SetupViewController";  


    UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:tabViewControllerIdentifier];
    AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];

    UIViewController *currentController = app.window.rootViewController;
    app.window.rootViewController = controller;
    app.window.rootViewController = currentController;

    [UIView transitionWithView:self.navigationController.view.window
                      duration:0.75
                       options:UIViewAnimationOptionTransitionFlipFromRight
                    animations:^{
                        app.window.rootViewController = controller;
                    }
                    completion:nil];
}

这将在控制器之间进行转换。您可以更改动画类型以适应您的需求。这是使用选项参数设置的;目前显示的是UIViewAnimationOptionTransitionFlipFromRight。


动画过渡对我没有任何效果。您为什么要将rootVC设置为目标视图控制器,然后在运行块之前再返回到源呢? - NYC Tech Engineer
没事了,已经通过这个SO链接解决了:https://dev59.com/GGsz5IYBdhLWcg3wNVAR - NYC Tech Engineer

1
这是一个比较老的问题。然而,我在我的应用程序中使用以下代码使其工作,并且我认为这是更好的解决方案。
[self addChildViewController:<# Your Split VC #>];
[<# Your Split VC #>.view willMoveToSuperview:self.view];
<# Your Split VC #>.view.frame = self.view.frame;
[self.view addSubview:<# Your Split VC #>.view];
[<# Your Split VC #>.view didMoveToSuperview];

这个想法是将视图控制器(父级)作为子级添加分割视图控制器。与任何其他控制器一样,对父级执行模型segue。

嗯,我不确定,但从iOS8开始,SplitViewController变得更好用了,可以在根视图控制器之外的其他地方使用它。

干杯!


0
如果您在故事板中创建了UISplitViewController,并在分割视图之前添加了主视图,则可以使用performSegueWithIdentifier来触发主视图和分割视图之间的转场。 要修复标题中的错误,您需要覆盖UISplitViewController中的一个方法。
// Swift
override func awakeFromNib() {
    let app = UIApplication.sharedApplication().delegate as AppDelegate

    let currentController = app.window!.rootViewController;
    app.window!.rootViewController = self;
}

在 Obj-C 中有没有一种方法可以做到这一点? - NYC Tech Engineer

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接