UISplitViewController和复杂的视图层次结构

时间:2010-04-14 19:01:10

标签: iphone ipad uikit uisplitviewcontroller

我正在进行iPad技术演示,我遇到了严重的技术问题。

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

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

主屏幕(UIViewController) 列表 - >详细信息“目录”(UISplitViewController) 超级细节屏幕(UIViewController但可以想象也是SplitView的孩子)。

问题在于Home和Catalog之间的流程。将UISplitViewController视图添加到UIWindow后,它就会开始出现混乱。

问题可归纳为:

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

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

然后我尝试简单地将SplitView作为“底部”视图保留,并保持从顶部添加和删除主屏幕,但这会失败,因为SplitView支配Orientation更改调用,而Home Screen不会即使您调用[homeScreen becomeFirstResponder]

,也会旋转

你不能将SplitView放入像UINavigationController这样的层次结构中,你会得到一个彻头彻尾的运行时错误,因此该选项不在桌面上。模态看起来很糟糕,无论如何都不鼓励。

我此时的推测是,处理这个问题的唯一正确方法是以某种方式“解除”UISplitViewController,以便可以从其父视图中删除它而不会抛出未处理的异常,但我不知道如何。< / p>

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

非常感谢帮助。

6 个答案:

答案 0 :(得分:8)

Apple states

  

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

这个确实意味着它应该是根视图而不是另一个视图的子视图。即使他们补充说:

  

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

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

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

答案 1 :(得分:4)

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

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

答案 2 :(得分:4)

我通过创建第二个UIWindow取得了一些成功。我将UISplitViewController与之关联,并在我想显示splitview时将其与主窗口一起切换。它似乎按照我想要的方式工作,除了旋转的轻微延迟和关于“wait_fences”的日志消息。

答案 3 :(得分:0)

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

此外,Gilt应用仅适用于美国

我一直试图找到一个解决方案,最终以编程方式从窗口删除视图,就像Tuannd谈到的那样,但景观渲染错误是不可原谅的。

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

答案 4 :(得分:0)

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

我似乎想出了一个解决我案子的办法,这似乎令人满意。

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

在我的情况下,我不希望UISplitView作为第一个视图。以下内容对我有用。

app委托应用程序: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];
     }
}

答案 5 :(得分:0)

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

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

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

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

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