* 用NavigationController來push出它的子控制器我們隨處可見,就這個過程的一些細節和父子控制器的關系,這里蛋疼的剖析一下,新手可能會碰到的疑問.
** 先說一個算是設計原理吧:當把一個控制器的view添加為自己的subview時,也要把控制器添加為自己的childViewController,這個人人皆知吧.**
- 再說幾個問題:
- 為什么這么做?
- 都是"子"(指subView,childViewController翻譯成中文),蘋果為什么要搞一個sub 一個chilid?
- 還有幾個在下面測試中關于NavigationController的子控制器個數的問題.
- 話不多少,正常開局. 設置ViewController為導航控制器根控制器
- 先交代下故事背景和我們要干啥: viewController是導航控制器的根控制器,在它的touchBegin方法中,push出一個黃色背景的ViewController.(這個很簡單,看代碼和圖片)
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
UIViewController *vc = [[UIViewController alloc]init];
vc.view.frame = self.view.bounds;
vc.view.backgroundColor = [UIColor yellowColor]; //黃的啊
[self.navigationController pushViewController:vc animated:YES];
}
Snip20151212_2.png
ok這個可以push成功了.
- 下一步我們自定義一個UIViewController ,這里是WSView,名字隨你.我們目的是把這個控制器的View添加到根控制器上面,后面要用.
- (void)viewDidLoad {
[super viewDidLoad];
WSViewC *vc1 = [[WSViewC alloc]init];
vc1.view.frame = CGRectMake(100, 100, 100, 101);
vc1.view.backgroundColor = [UIColor redColor];
[self.view addSubview:vc1.view]; //注意這里只添加了它的view
}
Snip20151212_3.png
//ok 這樣就有了紅色的view,就是WSViewController的View
*** 好,下面問題來了,我點擊這個紅色的View,也去監聽它的點擊,會不會觸發點擊?
**
- 答案是No,我們可以去touchBegin方法中打印,這里就不搞了,那我們現在想干這個事情: 我想通過點擊紅色的View也來Push出一個控制器,就像剛才那個Push出黃色的那家伙一樣,現在可以么? 先試試 .
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
UIViewController *vc = [[UIViewController alloc]init];
vc.view.frame = self.view.bounds;
vc.view.backgroundColor = [UIColor greenColor];//注意我換成綠色的為了區分是不是它push出來的
[self.navigationController pushViewController:vc animated:YES];
}
- 恩..結果是,push不出來,也就是說雖然紅色的View顯示在界面上,但是只是個樣子,并沒有控制器在控制它(很像Layer),不能和用戶交互.
所以說,當把一個控制器的view添加為自己的subview時,也要把控制器添加為自己的childViewController,添加后就可以了,就這么簡單
ViewController.m 中
- (void)viewDidLoad {
[super viewDidLoad];
WSViewC *vc1 = [[WSViewC alloc]init];
vc1.view.frame = CGRectMake(100, 100, 100, 101);
vc1.view.backgroundColor = [UIColor redColor];
[self.view addSubview:vc1.view];
**[self addChildViewController:vc1];** //增加了個這
}
Snip20151212_4.png
ok,綠色的出來了,同時要是點擊白色部分(也就是點擊到背景的那個控制器)會push出黃色.
- 這兒還問題來了:現在有:
- 1.ViewController能push
- 2.WSViewController自從添加成為ViewController的自控制器后也能push了
- 那么現在的NavigationController有幾個子控制器?都是誰?
Snip20151212_6.png
答案是: 2個;
他們分別是:ViewController 也就是根控制器,這沒啥說的一定是,另一個是push出來的控制器,那肯定了,能用導航控制器push出來,肯定是的.
那個,WSViewController自從添加成為ViewController的自控制器后也能push了,它咋不是呢?
- 這個疑惑可能來自于我們對View和SubView的理解. 這也是蘋果搞了個Sub 和Child的區別;
- 之前在學習UIView的時候我們到,像這個圖.
Snip20151212_8.png
** view3 是view2 的subView view2又是View1的subView,那么肯定View1有兩個subView**
NSLog(@"%zd",view1.subViews.count) // 兩個
- 但是這里不同的是,如果他們都是控制器的話,像剛才那樣的"繼承",VC3 是 VC2的子控制器, VC2 是 VC1的子控制器, 那么到頭來
NSLog(@"%zd",vc1.child.childViewControllers.count) // 1個
vc1只有一個自控制器,就是vc2.
- 所以這樣理解好一點: View SubView 像上司和下屬, 下屬可以有上級領導,上級領導也有可能有上級領導,但是,他們都是BOSS的下屬
- childViewController ,child 就是小孩兒的英文嘛!奏事說: 我有一個兒子,我兒子也有一個兒子,那么我兒子的兒子不是我的兒子. (:з」∠) ???????? 好了,念完這個繞口令,開頭的三個問題也解決了.