2013-07-19 58 views
1

有時我想用UIViewController作爲真正的「控制器」而不是帶有控制器的視圖。也就是說,UIViewController將獲得對現有UIView的控制權。如何在地球上設置一個UIViewController視圖爲零,使視圖失去了其超視圖?

在嵌套的UIViewcontroller中,我的UIViewController視圖是其他視圖的子視圖。

在某些情況下,UIViewController可能會控制相同的視圖,但不能同時進行。

所以在委託指派期間,我會確保先前的UIViewController停止註冊視圖,因爲它的視圖。

UITableView * tvDelegated = (UITableView *)self.delegateForTableController.tvDelegated; //Make sure tvDelegated is not deallocated 
UIViewController * vcPreviousViewController = [tvDelegated vcImmediateUIViewController]; 

assert(vcPreviousViewController.view==tvDelegated); 

PO(vcPreviousViewController.view); 
PO(vcPreviousViewController.view.superview); 
PO(tvDelegated); 
PO(tvDelegated.superview); 
vcPreviousViewController.view=nil;//if the table view used to have a different tableViewController then disassociate that 
PO(vcPreviousViewController.view); 
PO(vcPreviousViewController.view.superview); 
PO(tvDelegated); 
PO(tvDelegated.superview); 

基本上我存儲很強的指針到以前的ViewController的看法在一個名爲tvDelegated變量。這確保視圖不會消失。

結果,第一切正常:

self.BGtableController.view: <UITableView: 0x1dc0d600; frame = (0 0; 320 548); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x1e485850>; layer = <CALayer: 0x1e4e35b0>; contentOffset: {3, 10}> 
self.BGtableController.view.superview: <UIView: 0x1e4bd910; frame = (0 0; 320 548); autoresize = W+H; layer = <CALayer: 0x1e4bd970>> 
vcPreviousViewController.view: <UITableView: 0x1dc0d600; frame = (0 0; 320 548); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x1e485850>; layer = <CALayer: 0x1e4e35b0>; contentOffset: {3, 10}> 
vcPreviousViewController.view.superview: <UIView: 0x1e4bd910; frame = (0 0; 320 548); autoresize = W+H; layer = <CALayer: 0x1e4bd970>> 

vcPreviousViewController.view=nil執行如預期的那樣tvDelegated就不走了,但上海華走了。

vcPreviousViewController.view: <UITableView: 0x1dc0b000; frame = (0 0; 320 568); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x1e4cd330>; layer = <CALayer: 0x1e4cddd0>; contentOffset: {3, 10}> 
vcPreviousViewController.view.superview: (null) 
tvDelegated: <UITableView: 0x1dc0d600; frame = (0 0; 320 548); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x1e485850>; layer = <CALayer: 0x1e4e35b0>; contentOffset: {3, 10}> 
tvDelegated.superview: (null) 

這是另一件了不起的事情。 vcPreviousViewController.view不會成爲零。即使我清楚地將vcPreviousViewController.view設置爲nil,vcPreviousViewController.view.superview變成了nil。

回答

0

上UIViewController的視圖屬性蘋果文件說:

「每個視圖控制器對象是視圖的唯一擁有者不得使用多個視圖控制器對象相同的視圖對象關聯的唯一例外。容器視圖控制器實現可以將此視圖作爲子視圖添加到其自己的視圖層次結構中,在添加子視圖之前,容器必須首先調用其addChildViewController:方法在兩個視圖控制器對象之間創建父 - 子關係

如果您訪問此屬性並且其值目前爲零,則視圖控制器會自動調用loadView方法並將retu rns由此產生的看法。「

我想你會得到這種行爲,因爲你沒有調用UIViewController的父/子關係的正確方法。所以你可能會得到你的視圖的緩存版本,這是從視圖層次結構中拉出來的,因此沒有超視圖。

1

沒有理由使用UIViewController比。你可以從NSObject繼承你的類,但是沒關係。

使用委託如此棘手是一種不好的做法。你會收到更多像這樣的問題。

我該怎麼辦在同一案件:

1)一個畫面 - 一個視圖控制器。不要讓你的邏輯更復雜。將所有視圖的委託設置爲標準ViewController。

無論你需要:

2a)創建自定義類,可能singlton。看起來你需要像經理一樣的東西。2b)使用Notifactions機制,以防你不需要管理器之類的東西。它可以幫助您避免與委託鏈接頭痛。

+0

Jesly Varghese評論:更好地使用代表或塊(通知機制,如果過度使用,是很多頭疼) – kaspartus

+0

嗯。過度使用任何機制實際上是一種糟糕的做法。如果您的控制器必須與多於一個其他控制器通信,則委託機制不是最佳選擇。 – kaspartus

相關問題