UIViewController如何作為父容器管理子容器

UIViewController新增了作為容器添加子容器的方法

/*
  蘋果官方注釋
  These two methods are public for container subclasses to call when transitioning between child
  controllers. If they are overridden, the overrides should ensure to call the super. The parent argument in
  both of these methods is nil when a child is being removed from its parent; otherwise it is equal to the new
  parent view controller.

  addChildViewController: will call [child willMoveToParentViewController:self] before adding the
  child. However, it will not call didMoveToParentViewController:. It is expected that a container view
  controller subclass will make this call after a transition to the new child has completed or, in the
  case of no transition, immediately after the call to addChildViewController:. Similarly
  removeFromParentViewController: does not call [self willMoveToParentViewController:nil] before removing the
  child. This is also the responsibilty of the container subclass. Container subclasses will typically define
  a method that transitions to a new child by first calling addChildViewController:, then executing a
  transition which will add the new child's view into the view hierarchy of its parent, and finally will call
  didMoveToParentViewController:. Similarly, subclasses will typically define a method that removes a child in
  the reverse manner by first calling [child willMoveToParentViewController:nil].
*/

- (void)willMoveToParentViewController:(nullable UIViewController *)parent NS_AVAILABLE_IOS(5_0);
- (void)didMoveToParentViewController:(nullable UIViewController *)parent NS_AVAILABLE_IOS(5_0);
  • 當(dāng)在子視圖控制器與父視圖控制器與互相進(jìn)行過(guò)渡的時(shí)候,子視圖控制器可以調(diào)用這兩個(gè)公開的方法徽缚。

  • 如果重寫了這兩個(gè)方法,在重寫的方法里面一定要調(diào)用父視圖控制器的方法。

  • 當(dāng)子視圖控制器從他們的父視圖控制器中移除的時(shí)候类嗤,后面的parent參數(shù)都要填nil;否則擂啥,則要填新的父視圖控制器。

  • 當(dāng)某個(gè)子視圖控制器將從父視圖控制器中刪除時(shí)帆阳,parent參數(shù)為nil哺壶。
    即:[將被刪除的子試圖控制器 willMoveToParentViewController:nil];

  • 當(dāng)某個(gè)子試圖控制器將加入到父視圖控制器時(shí),parent參數(shù)為父視圖控制器。
    即:[將被加入的子視圖控制器 didMoveToParentViewController:父視圖控制器];

  • 當(dāng)調(diào)用 addChildViewController:這個(gè)方法添加子視圖控制器的時(shí)候变骡,會(huì)自動(dòng)調(diào)用[child willMoveToParentViewController:self]方法;
    然而离赫,這時(shí)候并不會(huì)去調(diào)用 didMoveToParentViewController:方法;

  • 因此

  1. 一個(gè)容器的子視圖控制器過(guò)渡到另一個(gè)子類控制器完成之后,會(huì)調(diào)用 didMoveToParentViewController: 方法
  2. 沒(méi)有過(guò)渡到另一個(gè)子類控制器, 當(dāng)調(diào)用 addChildViewController:方法后會(huì)馬上調(diào)用didMoveToParentViewController:方法
  • 相似的 用removeFromParentViewController:這個(gè)方法, 在移除子容器之前不會(huì)調(diào)用[self willMoveToParentViewController:nil] 方法
這也是父視圖控制器的職責(zé)
  • 父視圖控制器應(yīng)當(dāng)定義一個(gè)方法用于過(guò)渡到一個(gè)新的子視圖控制器, 方法里面要先調(diào)用addChildViewController:方法
    然后執(zhí)行過(guò)渡,執(zhí)行完之后會(huì)將子視圖控制器加到他的父視圖控制器之中塌碌,然后最后會(huì)調(diào)用didMoveToParentViewController:方法

  • 相似的渊胸,父視圖控制器需要定義一個(gè)相反的方式--來(lái)移除子容器的方法,方法需要首先調(diào)用 [child willMoveToParentViewController:nil]方法


以上是本人對(duì)這兩個(gè)方法的官方注釋的翻譯, 下面結(jié)合這些注釋談?wù)勥@兩個(gè)方法的使用

  • 在iOS 5.0之前,只能在UIViewController的View中通過(guò)addSubView的方法來(lái)添加子view台妆,而有一些View是不需要一直出現(xiàn)的翎猛,但是在ViewDidLoad之后,則會(huì)一起加載到內(nèi)存中接剩,影響性能的同時(shí)不方便管理切厘。
  • 在在iOS 5.0及以后,iOS為UIViewController類添加了新的屬性和方法:
@property(nonatomic,readonly) NSArray *childViewControllers

- (void)addChildViewController:(UIViewController *)childController
- (void) removeFromParentViewController
- (void)transitionFromViewController::::::
- (void)willMoveToParentViewController:(UIViewController *)parent
- (void)didMoveToParentViewController:(UIViewController *)parent

這樣懊缺,就能夠?qū)⒁粋€(gè)頁(yè)面中的UIViewController控制起來(lái)疫稿,而不是混亂的共用一個(gè)UIViewController,最重要的是鹃两,編程習(xí)慣的革命:降低了功能的耦合度遗座!

[父視圖控制器 addChildViewController:子視圖控制器];

在此,圖控制器A添加了另一個(gè)圖控制器B俊扳,那么A充當(dāng)父視圖控制器途蒋,B充當(dāng)子視圖控制器。父視圖控制器充當(dāng)了視圖控制器容器的角色馋记。

addChildViewController方法:

- (void)addChildViewController:(UIViewController *)childController

向視圖控制器容器中添加子視圖控制器


childController:子視圖控制器

當(dāng)要添加的子視圖控制器已經(jīng)包含在視圖控制器容器中号坡,那么,相當(dāng)于先從父視圖控制器中刪除梯醒,然后重新添加到父視圖控制器中宽堆。

removeFromParentViewController 方法

  • (void)removeFromParentViewController
    從父視圖控制器中刪除。

transitionFromViewController 方法

- (void)transitionFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion

交換兩個(gè)子視圖控制器的位置(由于添加的順序不同冤馏,所以子試圖控制器在父視圖控制器中存在層次關(guān)系)

fromViewController:當(dāng)前顯示的子試圖控制器日麸,將被替換為非顯示狀態(tài)
toViewController:將要顯示的子視圖控制器
duration:交換動(dòng)畫持續(xù)的時(shí)間寄啼,單位秒
options:動(dòng)畫的方式
animations:動(dòng)畫Block
completion:完成后執(zhí)行的Block

willMoveToParentViewController 方法

- (void)willMoveToParentViewController:(UIViewController *)parent

當(dāng)一個(gè)視圖控制器從視圖控制器容器中被添加或者被刪除之前逮光,該方法被調(diào)用

parent:父視圖控制器,如果沒(méi)有父視圖控制器墩划,將為nil

注意點(diǎn):

  1. 當(dāng)我們向我們的視圖控制器容器中調(diào)用removeFromParentViewController方法時(shí)涕刚,必須要先調(diào)用該方法,且parent參數(shù)為nil
[將要?jiǎng)h除的視圖控制器 willMoveToParentViewController:nil];
  • 當(dāng)我們調(diào)用addChildViewController方法時(shí)乙帮,在添加子視圖控制器之前將自動(dòng)調(diào)用該方法杜漠。所以,就不需要我們顯示調(diào)用了。
  1. 當(dāng)從一個(gè)視圖控制容器中添加或者移除viewController后驾茴,該方法被調(diào)用盼樟。
    parent:父視圖控制器,如果沒(méi)有父視圖控制器锈至,將為nil
//didMoveToParentViewController 方法
 - (void)didMoveToParentViewController:(UIViewController *)parent
  • 當(dāng)我們向我們的視圖控制器容器(就是父視圖控制器晨缴,它調(diào)用addChildViewController方法加入子視圖控制器,它就成為了視圖控制器的容器)中添加(或者刪除)子視圖控制器后峡捡,必須調(diào)用該方法击碗,告訴iOS,已經(jīng)完成添加(或刪除)子控制器的操作们拙。
  • removeFromParentViewController 方法會(huì)自動(dòng)調(diào)用了該方法稍途,所以,刪除子控制器后砚婆,不需要在顯示的調(diào)用該方法了械拍。

其實(shí),這幾個(gè)方法中的API說(shuō)明装盯,看的還懂殊者。

最后,

關(guān)于willMoveToParentViewController方法和didMoveToParentViewController方法的使用

  1. 這兩個(gè)方法用在子試圖控制器交換的時(shí)候調(diào)用验夯!即調(diào)用transitionFromViewController 方法時(shí)猖吴,調(diào)用。

  2. 當(dāng)調(diào)用willMoveToParentViewController方法或didMoveToParentViewController方法時(shí)挥转,要注意他們的參數(shù)使用:

  • 當(dāng)某個(gè)子視圖控制器將從父視圖控制器中刪除時(shí)海蔽,parent參數(shù)為nil
[將被刪除的子試圖控制器 willMoveToParentViewController:nil];
  • 當(dāng)某個(gè)子試圖控制器將加入到父視圖控制器時(shí)绑谣,parent參數(shù)為父視圖控制器党窜。
[將被加入的子視圖控制器 didMoveToParentViewController:父視圖控制器];
  1. 無(wú)需調(diào)用[子視圖控制器 willMoveToParentViewController:父視圖控制器]方法。因?yàn)槲覀冋{(diào)用[父視圖控制器 addChildViewController:子視圖控制器]時(shí)借宵,已經(jīng)默認(rèn)調(diào)用了幌衣。
    只需要在transitionFromViewController方法后,調(diào)用
[子視圖控制器didMoveToParentViewController:父視圖控制器]
  1. 無(wú)需調(diào)用[子視圖控制器 didMoveToParentViewController:父視圖控制器]方法壤玫。因?yàn)槲覀冋{(diào)用
    [子視圖控制器 removeFromParentViewController]時(shí)豁护,已經(jīng)默認(rèn)調(diào)用了。
    只需要在transitionFromViewController方法之前調(diào)用:
[子視圖控制器 willMoveToParentViewController:nil]
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末欲间,一起剝皮案震驚了整個(gè)濱河市楚里,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌猎贴,老刑警劉巖班缎,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蝴光,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡达址,警方通過(guò)查閱死者的電腦和手機(jī)蔑祟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)沉唠,“玉大人做瞪,你說(shuō)我怎么就攤上這事∮叶常” “怎么了装蓬?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)纱扭。 經(jīng)常有香客問(wèn)我牍帚,道長(zhǎng),這世上最難降的妖魔是什么乳蛾? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任暗赶,我火速辦了婚禮,結(jié)果婚禮上肃叶,老公的妹妹穿的比我還像新娘蹂随。我一直安慰自己,他們只是感情好因惭,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布岳锁。 她就那樣靜靜地躺著,像睡著了一般蹦魔。 火紅的嫁衣襯著肌膚如雪激率。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天勿决,我揣著相機(jī)與錄音乒躺,去河邊找鬼。 笑死低缩,一個(gè)胖子當(dāng)著我的面吹牛嘉冒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播咆繁,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼讳推,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了么介?” 一聲冷哼從身側(cè)響起娜遵,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蜕衡,失蹤者是張志新(化名)和其女友劉穎壤短,沒(méi)想到半個(gè)月后设拟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡久脯,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年纳胧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片帘撰。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡跑慕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出摧找,到底是詐尸還是另有隱情核行,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布蹬耘,位于F島的核電站芝雪,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏综苔。R本人自食惡果不足惜惩系,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望如筛。 院中可真熱鬧堡牡,春花似錦、人聲如沸杨刨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)妖胀。三九已至可免,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間做粤,已是汗流浹背浇借。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留怕品,地道東北人妇垢。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像肉康,于是被迫代替她去往敵國(guó)和親闯估。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容