2010-04-14 62 views
9

我正在做一个iPad的技术演示,我遇到了一个严重的技术问题。UISplitViewController和复杂的视图层次

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

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

主屏幕(UIViewController中) 列表 - >详细“目录”(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

我已经解决了这个我自己......其实工作围绕...通过介绍所有其他可能的全屏视图的SPLITVIEW的模态...

这是做事情的方式令人厌恶的我但如果您想在应用程序中仅“有时”使用SplitView,苹果公司就没有多少选择。

+0

嘿Jasconius ..我试图做同样的,因为你甚至我正在看Gilt的应用程序。我需要确切的same.can你发布一些示例代码?这将是很大的帮助..感谢 – Nnp 2010-10-07 20:52:47

+0

是的,这正是我们在Gilt应用程序中所做的。 SplitViewController在另一个控制器中确实不能很好地发挥作用,所以我们坚持使用模态视图来远离分割视图进行导航。 – jexe 2011-01-01 23:06:39

+0

请查看我的[custom UISplitViewController](http://iphone-dev-tips.alterplay.com/2011/05/custom-uisplitviewcontroller-for-ipad.html)。它确实能够满足你的需求。 – slatvick 2011-05-02 07:58:23

8

苹果states

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

This does表示它应该是根视图而不是其他视图的子视图。即使他们增加:

你不应该提出一个导航或标签栏界面

这并不意味着你可以将其添加任何其他控制器的一个子视图的内部拆分视图。 (抱歉)

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

+0

正确。我实际上已经“暂时”解决了这个问题,但是将SplitView作为根,并将所有其他视图呈现为具有过渡的全屏模态。我敢打赌,GILT可能正在做一些与自定义模式转换类似的事情。 苹果公司将释放出如此巨大的实用性的控制权,并带来如此多的限制,这是非常令人沮丧的。 苹果的指导方针也针对过度使用情态规定......但是在这种情况下他们给了我们什么选择? – 2010-04-15 21:03:13

4

我通过创建第二个UIWindow获得了一些成功。我将UISplitViewController与此相关联,并且当我想要显示splitview时,将其与主窗口切换出来。它似乎以我想要的方式工作,除了稍微延迟旋转以及关于“wait_fences”的日志消息。

+0

好主意。那么处理方向变化的方式有多优雅? – 2010-05-04 19:09:35

+1

似乎工作正常。无论哪个窗口都可见,两个窗口的方向都跟踪设备的物理方向,就像您所期望的那样。唯一的缺点是“wait_fences”错误在旋转中产生轻微的视觉呃逆。可能不是生产质量,但足够我的演示。 – g051051 2010-05-04 19:18:47

+0

如何切换应用程序的窗口? – MikeN 2011-03-01 22:15:37

0

除非你开发的监狱破碎设备,然后弯曲苹果规则/愿望不是一个好主意。就像Jann和Jasconius所说的那样,这意味着保持splitView控制器视图的根目录,而不是过度使用模态(模糊)而不使用多个窗口。

此外,Gilt应用仅在美国上市

心中已经一直试图找到一个解决方案也和已经结束了从像约Tuannd洽谈但窗口编程去除意见景观渲染错误是不可饶恕。

@Jasconius,你在任何时候呈现的模态的最大数量是多少?

+0

好吧,不要超过一个,因为这似乎是你可以轻松逃脱的一切。如果我必须手动放置子视图,我现在就关闭这个项目,并为iPad提供全新的自定义控件。 iPad的定位管理只是一个可恶的耻辱。 – 2010-07-05 15:02:13

0

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

我似乎想出了一个解决方案,我的情况似乎正在令人满意地工作。

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

在我的情况下,我不希望UISplitView作为第一个视图。以下为我工作。

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

这是一个关于添加然后删除appDidFinishLaunching中的拆分视图的好洞察。 “根视图控制器”和错误的定位通知已经成为一个已经确立的问题,SplitView不能作为子视图这一事实完全加剧了这个问题。在一个合理的宇宙中(阅读:基本上任何不使用SplitView的应用程序),您总是会有一个通用的RVC,向其子节点发送方向信息。 Splitview粉碎了这个。你最好从字面上制作你自己的Splitview。 – 2010-09-17 20:53:28

0

的实例变量只想说我是运行到这些同样的问题,发现这个论坛主题,并从上面g051051遵循的建议。这对我来说是完美的。我没有看到任何故障,并且没有关于设备控制台中的wait_fences的消息。

我简单地使用IB在主XIB中创建了两个UIWindow对象,正常情况下创建了UISplitViewController,然后还创建了从UIViewController(我用于全屏显示)派生的其他控制器的实例。我只需将每个UIWindow的rootViewController连接到相应的控制器就可以将它们连接起来。

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

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

无论如何,对我来说很好,而且其实很容易设置。

+0

其实,一个怪癖:在XIB中设置UIWindows的rootViewControllers会导致一个小问题。问题是,当以纵向模式启动时,UISplitViewControllerDelegate的方法splitViewController:willHideViewController:...方法最初不会被调用,因此可以添加UIBarButtonItem。如果将splitViewController.view明确添加为应用程序中的UIWindow的子视图:didFinishLaunchingWithOptions:,则会正确调用此初始委托方法。 – Eric 2011-05-06 14:41:58