2010-04-14 59 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