什麼是Container View Controller?蘋果文檔是這麼描述的: app
A container view controller contains content owned by other view controllers. |
也就是說一個View Controller顯示的某部份內容屬於另外一個View Controller,那麼這個View Controller就是一個Container,好比UIKit中的UINavigationController,UITabBarController。 spa
在iOS 5以前蘋果是不容許出現自定義的Container的 ,也就是說你建立的一個View Controller的view不能包含另外一個View Controller的view,這對於邏輯複雜的界面來講,不易於功能拆分。也許曾經你爲了某個公用的顯示邏輯,直接將某個View Controller的view添加到另外一個View Controller的view上,而後發現能夠正常顯示和使用,但實際上這種行爲是很是危險的。 code
iOS 5.0 開始支持Custom Container View Controller,開放了用於構建自定義Container的接口。若是你想建立一個本身的Container,那麼有一些概念還得弄清楚。Container的主要職責就是管理一個或多個Child View Controller的展現的生命週期,須要傳遞顯示以及旋轉相關的回調。 接口
其實顯示或者旋轉的回調的觸發的源頭來自於window,一個app首先有一個主window,初始化的時候須要給這個主window指定一個rootViewController,window會將顯示相關的回調(viewWillAppear:, viewWillDisappear:, viewDidAppear:, or viewDidDisappear: )以及旋轉相關的回調(willRotateToInterfaceOrientation:duration: ,willAnimateRotationToInterfaceOrientation:duration:, didRotateFromInterfaceOrientation:)傳遞給rootViewController。rootViewController須要再將這些callbacks的調用傳遞給它的Child View Controllers。 生命週期
一. 父子關係範式 ci
實現一個Custom Container View Controller並非一個簡單的事情,主要分爲兩個階段:父子關係的創建以及父子關係的解除。若是pVC將cVC的view添加爲本身的subview,那麼cVC必須爲pVC的Child View Controller,而反過來則不必定成立,好比UINavigationController,一個View Controller被push進來後便和navigationController創建父子關係了,可是隻有最上面的View Controller 是顯示着的,底下的View Controller的view則被移出了容器的view的顯示層級,當一個View Controller被pop以後,便和navigationController解除了父子關係了。 rem
展現一個名爲content的child view controller: 文檔
- [self addChildViewController:content]; //1
- content.view.frame = [self frameForContentController];
- [self.view addSubview:self.currentClientView]; //2
- [content didMoveToParentViewController:self]; //3
1.將content添加爲child view controller,addChildViewController:接口創建了邏輯上的父子關係,子能夠經過parentViewController,訪問其父VC,addChildViewController:接口的邏輯中會自動調用 [content willMoveToParentViewController:self]; it
2.創建父子關係後,即是將content的view加入到父VC的view hierarchy上,同時要決定的是 content的view顯示的區域範圍。 io
3.調用child的 didMoveToParentViewController: ,以通知child,完成了父子關係的創建
移除一個child view controller:
- [content willMoveToParentViewController:nil]; //1
- [content.view removeFromSuperview]; //2
- [content removeFromParentViewController]; //3
1.通知child,即將解除父子關係,從語義上也能夠看出 child的parent即將爲nil
2.將child的view從父VC的view的hierarchy中移除
3.經過removeFromParentViewController的調用真正的解除關係,removeFromParentViewController會自動調用 [content didMoveToParentViewController:nil]