iOS addChildViewController實(shí)現(xiàn)控制器容器的相關(guān)知識(shí)

前言

控制器容器Container的主要職責(zé)就是管理一個(gè)或多個(gè)Child View Controller的展示的生命周期夷狰,需要傳遞顯示以及旋轉(zhuǎn)相關(guān)的回調(diào)。能夠有效的分離業(yè)務(wù)邏輯、減輕一些復(fù)雜控制器的復(fù)雜度,有利于代碼的理解與維護(hù)。

相關(guān)知識(shí)

顯示或者旋轉(zhuǎn)的回調(diào)的觸發(fā)的源頭來(lái)自于window,一個(gè)app首先有一個(gè)主window帮毁,初始化的時(shí)候需要給這個(gè)主window指定一個(gè)rootViewController,window會(huì)將顯示相關(guān)的回調(diào)(viewWillAppear:, viewWillDisappear:, viewDidAppear:, or viewDidDisappear: )以及旋轉(zhuǎn)相關(guān)的回調(diào)(willRotateToInterfaceOrientation:duration: ,willAnimateRotationToInterfaceOrientation:duration:, didRotateFromInterfaceOrientation:)傳遞給rootViewController豺撑。rootViewController需要再將這些callbacks的調(diào)用傳遞給它的Child View Controllers烈疚。

展示子控制器

[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:接口建立了邏輯上的父子關(guān)系聪轿,子可以通過(guò)parentViewController爷肝,訪問(wèn)其父VC,addChildViewController:接口的邏輯中會(huì)自動(dòng)調(diào)用 [content willMoveToParentViewController:self];
2.建立父子關(guān)系后陆错,便是將content的view加入到父VC的view hierarchy上灯抛,同時(shí)要決定的是 content的view顯示的區(qū)域范圍。
3.調(diào)用child的 didMoveToParentViewController: 音瓷,以通知child对嚼,完成了父子關(guān)系的建立

移除子控制器

[content willMoveToParentViewController:nil]; //1 
[content.view removeFromSuperview]; //2 
[content removeFromParentViewController]; //3 

1.通知child,即將解除父子關(guān)系绳慎,從語(yǔ)義上也可以看出 child的parent即將為nil
2.將child的view從父VC的view的hierarchy中移除
3.通過(guò)removeFromParentViewController的調(diào)用真正的解除關(guān)系纵竖,removeFromParentViewController會(huì)自動(dòng)調(diào)用 [content didMoveToParentViewController:nil]

appearance callbacks的傳遞

上面的實(shí)現(xiàn)中有一個(gè)問(wèn)題,就是沒(méi)看到那些appearance callbacks是如何傳遞的杏愤,答案就是appearance callbacks默認(rèn)情況下是自動(dòng)調(diào)用的靡砌,蘋(píng)果框架底層幫你實(shí)現(xiàn)好了,也就是在上面的addSubview的時(shí)候珊楼,在subview真正加到父view之前通殃,child的viewWillAppear將被調(diào)用,真正被add到父view之后厕宗,viewDidAppear會(huì)被調(diào)用画舌。移除的過(guò)程中viewWillDisappear堕担,viewDidDisappear的調(diào)用過(guò)程也是類(lèi)似的。

有時(shí)候自動(dòng)的appearance callbacks的調(diào)用并不能滿足需求骗炉,比如child view的展示有一個(gè)動(dòng)畫(huà)的過(guò)程,這個(gè)時(shí)候我們并不想viewDidAppear的調(diào)用在addSubview的時(shí)候進(jìn)行蛇受,而是等展示動(dòng)畫(huà)結(jié)束后再調(diào)用viewDidAppear句葵。

也許你可能會(huì)提到 transitionFromViewController:toViewController:duration:options:animations:completion: 這個(gè)方法,會(huì)幫你自動(dòng)處理view的add和remove兢仰,以及支持animations block乍丈,也能夠保證在動(dòng)畫(huà)開(kāi)始前調(diào)用willAppear或者willDisappear,在調(diào)用結(jié)束的時(shí)候調(diào)用didAppear把将,didDisappear轻专,但是此方式也存在局限性,必須是兩個(gè)新老子VC的切換察蹲,都不能為空请垛,因?yàn)橐WC新老VC擁有同一個(gè)parentViewController,且參數(shù)中的viewController不能是系統(tǒng)中的container洽议,比如不能是UINavigationController或者UITabbarController等宗收。

有時(shí)候并不想使用默認(rèn)情況下的自動(dòng)調(diào)用,那么shouldAutomaticallyForwardAppearanceMethods方法并返回NO就可以禁止系統(tǒng)的默認(rèn)調(diào)用亚兄。

手動(dòng)傳遞的時(shí)候你并不能直接去調(diào)用child 的viewWillAppear或者viewDidAppear這些方法混稽,而是需要使用 beginAppearanceTransition:animated:和endAppearanceTransition接口來(lái)間接觸發(fā)那些appearance callbacks,且begin和end必須成對(duì)出現(xiàn)审胚。[content beginAppearanceTransition:YES animated:animated]觸發(fā)content的viewWillAppear匈勋,[content beginAppearanceTransition:NO animated:animated]觸發(fā)content的viewWillDisappear,和他們配套的[content endAppearanceTransition]分別觸發(fā)viewDidAppear和viewDidDisappear膳叨。

rotation callbacks的傳遞

也許在iPhone上很少要關(guān)心的屏幕旋轉(zhuǎn)問(wèn)題的洽洁,但是大屏幕的iPad上就不同了,很多時(shí)候你需要關(guān)心橫豎屏菲嘴。rotation callbacks 一般情況下只需要關(guān)心三個(gè)方法 willRotateToInterfaceOrientation:duration:在旋轉(zhuǎn)開(kāi)始前诡挂,此方法會(huì)被調(diào)用;willAnimateRotationToInterfaceOrientation:duration: 此方法的調(diào)用在旋轉(zhuǎn)動(dòng)畫(huà)block的內(nèi)部临谱,也就是說(shuō)在此方法中的代碼會(huì)作為旋轉(zhuǎn)animation block的一部分璃俗;didRotateFromInterfaceOrientation:此方法會(huì)在旋轉(zhuǎn)結(jié)束時(shí)被調(diào)用。而作為view controller container 就要肩負(fù)起旋轉(zhuǎn)的決策以及旋轉(zhuǎn)的callbacks的傳遞的責(zé)任悉默。

禁掉默認(rèn)調(diào)用需要重寫(xiě)兩個(gè)方法 shouldAutorotate和supportedInterfaceOrientations,前者決定再旋轉(zhuǎn)的時(shí)候是否去根據(jù)supportedInterfaceOrientations所支持的取向來(lái)決定是否旋轉(zhuǎn)城豁,也就是說(shuō)如果shouldAutorotate返回YES的時(shí)候,才會(huì)去調(diào)用supportedInterfaceOrientations檢查當(dāng)前view controller支持的取向抄课,如果當(dāng)前取向在支持的范圍中唱星,則進(jìn)行旋轉(zhuǎn)雳旅,如果不在則不旋轉(zhuǎn);而當(dāng)shouldAutorotate返回NO的時(shí)候间聊,則根本不會(huì)去管supportedInterfaceOrientations這個(gè)方法攒盈,反正是不會(huì)跟著設(shè)備旋轉(zhuǎn)就是了。

作為控制器容器需要注意的就是你需要去檢查你的child view controller哎榴,檢查他們對(duì)橫豎屏的支持情況型豁,以便容器自己決策在橫豎屏旋轉(zhuǎn)時(shí)候是否支持當(dāng)前的取向,和上面的callbacks傳遞的方向相比尚蝌,這其實(shí)是一個(gè)反向的傳遞迎变。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市飘言,隨后出現(xiàn)的幾起案子衣形,更是在濱河造成了極大的恐慌,老刑警劉巖姿鸿,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谆吴,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡苛预,警方通過(guò)查閱死者的電腦和手機(jī)纪铺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)碟渺,“玉大人鲜锚,你說(shuō)我怎么就攤上這事∩慌模” “怎么了芜繁?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)绒极。 經(jīng)常有香客問(wèn)我骏令,道長(zhǎng),這世上最難降的妖魔是什么垄提? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任榔袋,我火速辦了婚禮,結(jié)果婚禮上铡俐,老公的妹妹穿的比我還像新娘凰兑。我一直安慰自己,他們只是感情好审丘,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布吏够。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪锅知。 梳的紋絲不亂的頭發(fā)上播急,一...
    開(kāi)封第一講書(shū)人閱讀 49,950評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音售睹,去河邊找鬼桩警。 笑死,一個(gè)胖子當(dāng)著我的面吹牛昌妹,可吹牛的內(nèi)容都是我干的捶枢。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼捺宗,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼柱蟀!你這毒婦竟也來(lái)了川蒙?” 一聲冷哼從身側(cè)響起蚜厉,我...
    開(kāi)封第一講書(shū)人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎畜眨,沒(méi)想到半個(gè)月后昼牛,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡康聂,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年贰健,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恬汁。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡伶椿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出氓侧,到底是詐尸還是另有隱情脊另,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布约巷,位于F島的核電站偎痛,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏独郎。R本人自食惡果不足惜踩麦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望氓癌。 院中可真熱鬧谓谦,春花似錦、人聲如沸贪婉。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至星压,卻和暖如春践剂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背娜膘。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工逊脯, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人竣贪。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓军洼,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親演怎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子匕争,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

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