為什么要使用父子控制器
- 有的應用中tabBarController已經滿足不了界面的需求.
- 有的應用也許在tabBarController上顯示的是首頁
-
但是首頁卻又參雜了許許多多的頁面(比如視頻,音頻,圖片,文字)
比如這個:
如上圖所示: tabBarController是無法完成這個功能的
所以我們要換一個實現的思路.一步步來搞明白父子控制器的重要性
-
首先新建一個項目,在Storyboard中拖入這樣的控件
Snip20150921_128.png One Two Three任意點擊某一個按鈕就會切換一個控制器
-
接下來讓
one為tabViewController,并且設置上數據
Two為viewController.給這個view創建XIB并且附上顏色
Three為viewController. 給這個view創建XIB并且附上顏色
Snip20150921_129.png
我們來看下展示出來的效果
Snip20150921_130.png
Snip20150921_132.png
Snip20150921_131.png
存在的問題
1.重復創建過多的控制器(當我來回點擊三個按鈕的時測試出現的問題)
2.這個我給one控制器設置的數據,可是沒有顯示出來.
3.控制器已經死了,但是控制器的view還在
原因:
- 3個問題的原因都是因為控制器死了.
- 而view通過addSubView被添加在了主控制器上.
我們在每個控制器中打印dealloc看看,點擊了按鈕跳轉到相應的控制器后的打印結果
每當點擊一個控制器,上一次點擊的控制器就死了.
1.重復創建過多的控制器解決方法
給控制器強引用并且懶加載
-
強引用控制器可以使其不死
Snip20150921_141.png -
懶加載可以讓控制器無論點擊多少下,控制器之創建一次
Snip20150921_142.png
這樣的話就可以解決上面的3個問題了,其實還是很簡單的.
可是當我點開調試軟件的時候第四個問題又出現了.....
3個view都同時顯示在控制器上
我們想要的目的是點擊哪個控制器,那么那個被點擊的控制器就顯示在view上.但不是3個都顯示.
3個view都同時顯示在控制器上解決方法
解決思路:
-
在每一個按鈕方法中寫出將其他2個控制器移除的代碼
Snip20150921_145.png -
在每一個按鈕方法中寫出將其他2個控制器移除的代碼
Snip20150921_146.png -
這樣就可以在點擊其他view的時候,原先的view就可以移除
Snip20150921_147.png
這樣,這幾個問題就都一一的解決了(控制器上,只有點擊對應按鈕的控制器才會存在)
Snip20150921_148.png
這里要提示的一點是: removeFromSuperView:不是銷毀控制器 ,而是將控制器從父控件中移除.因為在創建屬性的時候用強引用strong引用著.被移除的控制器是存在于內存中
當我覺得一切都搞定了以后,又想到一個新的問題:
如果在第二個界面的按鈕我想要監聽點擊事件,怎么辦呢
或者第三個界面我想監聽某個控件怎么辦呢
于是打印后得到的值,只是viewController的監聽,而不是內部控制器的監聽.為什么呢
因為,你創建的3個控制器跟viewController一丁點的關系都沒有
所以這個時候就要牽扯到關系的建立的問題了,
扯了這么多,我們來正式介紹下父子控制器
讓one two three成為viewController的兒子就可以了
這時候我們要先知道蘋果提供了的兩個方法
// 添加控制器到數組中
self.addChildViewController = [[oneViewController alloc] init];
//也就是添加到了下面這個數組中
self.childViewControllers
- 只要通過
self.addChildViewController
這個方法添加的子控制器最后都會出現在self.childViewControllers
這個數組中,那么,我用到的時候就可以通過self.childViewControllers
這個方法取出對應的索引來使用他的子控制器.
那么,為什么要使用這個方法呢?
- 為了保住這3個家伙的命,讓他們不死,
- 通過索引方便取出
- 保證父控制器和子控制器的父子關系
-
只要保證他們之間的關系,那么父控制器只要有任何的重要改變的事件,內部的也都會跟著改變.
Paste_Image.png
那么既然可以添加,就一定會有移除的需求
Paste_Image.png
控制器父子關系的建立原則
- 如果2個控制器的view是父子關系(不管是直接還是間接的父子關系),那么這2個控制器也應該為父子關系
[a.view addSubview:b.view];
[a addChildViewController:b];
// 或者
[a.view addSubview:otherView];
[otherView addSubbiew.b.view];
[a addChildViewController:b];
獲得所有的子控制器
@property(nonatomic,readonly) NSArray *childViewControllers;
添加一個子控制器
//XMGOneViewController成為了self的子控制器
//self成為了XMGOneViewController的父控制器
[self addChildViewController:[[XMGOneViewController alloc] init]];
// 通過addChildViewController添加的控制器都會存在于childViewControllers數組中
獲得父控制器
@property(nonatomic,readonly) UIViewController *parentViewController;
將一個控制器從它的父控制器中移除
// 控制器a從它的父控制器中移除
[a removeFromParentViewController];