【问题标题】:"Application tried to present Split View Controllers modally"“应用程序试图以模态方式呈现拆分视图控制器”
【发布时间】:2013-12-18 01:36:28
【问题描述】:

我仍在尝试找到一个解决方案来解决理论上非常简单的任务,即从 UIViewController 到拆分视图控制器。 (为什么苹果让这件事变得如此困难)。

我现在将SplitViewController 放入它自己的情节提要中。 当用户在单个 UIView 控制器上选择一个按钮时,我调用以下代码:

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

所以我想用 splitview 控制器加载情节提要。 但这也会因“应用程序试图以模态方式呈现拆分视图控制器”而崩溃

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

有没有办法解决这个问题?

【问题讨论】:

    标签: ios ipad uisplitviewcontroller


    【解决方案1】:

    UISplitViewController 必须始终是根视图控制器,并且不能以模态方式呈现。见Apple docs,上面写着:

    拆分视图控制器必须始终是您的任何界面的根 创建。换句话说,您必须始终从 UISplitViewController 对象作为应用程序的根视图 窗户。然后,您的拆分视图界面的窗格可能包含 导航控制器、标签栏控制器或任何其他类型的视图 你需要实现你的接口的控制器。拆分视图 控制器不能以模态方式呈现。

    【讨论】:

    • 我可以将 SplitViewController 嵌入到 TabViewController 中,然后转到 TabViewController。为什么苹果在这件事上大做文章。
    • 我不知道,但他们是实施所有这些东西的人......如果你不遵循他们的建议和规则,你迟早会遇到麻烦。
    • 苹果或任何人是否提供了一种模式或知道如何在您进入拆分视图之前呈现视图? IE 登录是一个很常见的场景。登录后如何呈现常规登录视图并转换到拆分视图控制器?同样,如果苹果想成为应用程序的根视图控制器,违反它或解决方法可能不是一个好主意。
    • 自 iOS 8 以来不再如此。
    • 即使 iOS7 也不是这样,..您可以以模态方式呈现 splitView,但您需要在 awakeFromNib 中创建 splitView rootController,特别是在 iOS7 中,正如 Alex 所说。在 iOS 8 中不需要。
    【解决方案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 设置为目标视图控制器,然后在运行块之前返回源?
    • 没关系,使用这个 SO:stackoverflow.com/questions/8053832/…
    【解决方案3】:

    这是一个很老的问题。但是我在我的应用程序中使用下面的代码让它工作了,我认为这是更好的解决方案。

    [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 变得更好了,应该可以在根视图控制器以外的其他地方使用它。

    干杯!

    【讨论】:

      【解决方案4】:

      如果您在情节提要中创建了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 中做到这一点?
      【解决方案5】:

      是的,可以从 UIView 传递到 UISplitView。您必须使用自定义转场。

      阅读此链接(从日语翻译)

      UIViewController to UISplitViewController

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-11
        • 2023-01-25
        • 1970-01-01
        • 2023-03-18
        • 2013-01-06
        • 2011-12-25
        • 1970-01-01
        相关资源
        最近更新 更多