9

我正在做一个 iPad 技术演示,我遇到了一个严重的技术问题。

我有一个利用 UISplitViewController 的应用程序概念,但不是作为整个应用程序的主控制器。

应用流程大致可以这样描述:

主屏幕 (UIViewController) List->Detail "Catalog" (UISplitViewController) 超级详细屏幕(UIViewController 但也可能是 SplitView 的子项)。

问题在于 Home 和 Catalog 之间的流程。一旦 UISplitViewController 视图被添加到 UIWindow 中,它就会开始发出嘶嘶声。

问题可以总结为:

当 UISplitView 生成一个弹出视图时,它似乎被锁定到其父视图。从 UIWindow 子视图中删除 UISplitView 后,您将收到 CoreGraphics 异常,并且该视图将无法删除。

添加其他视图时(在这种情况下可能是您要返回的主屏幕),它们不会自动旋转,而是由于 CG 异常而无法删除的 UISplitView 继续响应旋转,导致无法仅“处理”的可怕渲染错误。此时,添加任何视图,甚至重新添加 SplitView,都会导致一连串的渲染错误。

然后,我尝试简单地将 SplitView 保留为“底部”视图,并继续从其顶部添加和删除主屏幕,但这失败了,因为 SplitView 支配了方向更改调用,并且主屏幕不会旋转,甚至如果您致电 [homeScreen becomeFirstResponder]

您不能将 SplitView 放入 UINavigationController 之类的层次结构中,您将得到一个彻底的运行时错误,因此该选项不可用。模态只是看起来很糟糕,无论如何都不鼓励。

我现在的假设是,处理这个问题的唯一正确方法是以某种方式“解除” UISplitViewController 以便可以将其从其父视图中删除而不会引发未处理的异常,但我不知道如何。

如果您想查看完全符合我需要的应用程序,请查看 iPad 应用程序商店中的 GILT Groupe。他们成功了,但他们似乎已经编写了一个完整的自定义视图转换集。

帮助将不胜感激。

4

6 回答 6

8

苹果表示

拆分视图控制器的视图应始终安装为应用程序窗口的根视图。您永远不应该在导航或标签栏界面内显示拆分视图。

确实意味着它应该是根视图,而不是另一个视图的子视图。即使他们添加:

您永远不应该在导航或标签栏界面内显示拆分视图

这并不意味着您也可以将其添加为任何其他控制器的子视图。(对不起)

我有一种感觉,你正在经历的是尝试这样做的副产品。我真的很惊讶GILT Groupe的应用程序没有被拒绝。Apple 最近倾向于严格执行这些 HIG 准则。当您尝试将它们添加到 NavigationController 时,它们(正如您已经发现的那样)会导致相当讨厌的运行时错误。

于 2010-04-15T04:19:07.607 回答
4

我已经为自己解决了这个问题......实际上已经解决了......通过将所有其他可能的全屏视图呈现为 SplitView 的模态......

在我的书中,这是一种令人讨厌的做事方式,但如果您只想在应用程序中“有时”利用 SplitView,Apple 会让您别无选择。

于 2010-04-15T21:04:12.673 回答
4

我通过创建第二个 UIWindow 取得了一些成功。我将 UISplitViewController 与它相关联,并在我想显示拆分视图时将其与主窗口切换。它似乎按照我想要的方式工作,除了轮换略有延迟和有关“wait_fences”的日志消息。

于 2010-05-03T15:26:33.243 回答
0

除非您为越狱设备开发,否则弯曲苹果规则/愿望不是一个好主意。像上面的 Jann 和 Jasconius 状态一样,这意味着保持 splitView 控制器视图根,而不是过度使用模式(模糊)并且不使用多个窗口。

此外,Gilt应用程序仅在美国可用

我也一直在尝试寻找解决方案,并最终以编程方式从窗口中删除视图,就像 Tuannd 所说的那样,但是景观渲染错误是不可原谅的。

@Jasconius,您随时展示的最大模态数是多少?

于 2010-07-04T12:00:15.860 回答
0

我正在努力解决同样的问题。我一直在尝试将 UISplitViewController 作为黑匣子戳各种东西,看看它是如何反应的。

我似乎已经想出了一个解决方案来解决我的问题,这似乎工作得令人满意。

关键似乎是添加到 UIWindow 的第一个视图是唯一正确初始化的视图。我遇到的所有问题往往源于设备方向的错误通知。添加的第一个视图显然已正确配置。

就我而言,我不希望 UISplitView 作为第一个视图。以下对我有用。

应用委托 application:didFinishLaunching 方法很特殊。必须在此处将视图添加到 UIWindow。如果它在其他地方完成,则不会正确配置。

本质上,魔术酱是让拆分视图成为添加到窗口的第一个视图。只要您保留 UISplitViewController,就可以将其删除。从那时起,您可以交换其他视图,包括 UISplitView 和大多数事情似乎没问题。

我仍然遇到了一些问题。拆分视图以外的视图上的弹出框在视图框架和工具栏按钮的位置上会混淆,并将显示在错误的位置。然后我将其放置在特定位置,这似乎可以处理这种情况。

如果拆分视图上的弹出框仍然显示,并且您尝试查看另一个视图,则第二个视图的方向会混淆并横向显示。如果在显示弹出窗口之前访问该视图,则一切正常。我已经解决了这个问题,我在切换到任何其他视图之前手动关闭了弹出框。

如果有帮助,这是代码。所有的控制器都是 appDelegate 的实例变量

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // This also seems to work as good magic. Seems to set orientation and size properties that persist.
    [window addSubview:splitViewController.view];
    [splitViewController.view removeFromSuperview];

    [self switchToNewViewController:firstController];
    [window makeKeyAndVisible];
    return TRUE;
}

- (void)switchToNewViewController:(UIViewController *)newViewController {
    [popoverController dismissPopoverAnimated:FALSE];
    if (newViewController != currentViewController) {
        [currentViewController removeFromSuperview];
        currentViewController = newViewController;
        [window addSubView:newViewController.view];
     }
}
于 2010-09-17T19:35:28.227 回答
0

只是想说我遇到了同样的问题,找到了这个论坛主题,并遵循了上面 g051051 的建议。这对我来说非常有效。我没有看到任何故障,也没有在设备控制台中看到有关 wait_fences 的消息。

我只是使用 IB 在主 XIB 中创建了两个 UIWindow 对象,正常创建了 UISplitViewController,然后还创建了从 UIViewController 派生的另一个控制器的实例(我用于全屏显示)。我只是通过将每个 UIWindow 的 rootViewController 附加到其适当的控制器来将它们连接起来。

在 application:didLaunch...: 方法中,我可以决定向哪个窗口发送 makeKeyAndVisible 方法以及将哪个窗口设置为隐藏。当用户想要来回切换时,我只需将 makeKeyAndVisible 发送给一个并在另一个上设置 hidden 属性,这就是它的全部内容。

如所指示的,所有与旋转相关的消息都被适当地发送到每个控制器,而不管哪个与当前可见窗口相关联。

无论如何,对我来说效果很好,而且实际上很容易设置。

于 2011-05-06T12:59:57.650 回答