一.前言:
開發(fā)中苦银,我們經(jīng)常需要將一個(gè)控制器的view添加到另一個(gè)控制器的view上,這種效果是我們期望看到的,但是里邊隱藏著一些細(xì)節(jié)幔虏,不注意的話纺念,可能會(huì)達(dá)不到我們想到的效果。以往只是用過想括,并沒有意識(shí)到這其實(shí)是一種模型陷谱,也沒想過它的應(yīng)用場景,更沒有推敲其中的細(xì)節(jié)之處瑟蜈,看了別人的文檔烟逊,也只是只言片語,這里自己把所理解的總結(jié)一下铺根,便于以后回頭看宪躯,理解的更清晰,使用起來更熟練
二.蘋果官方:
當(dāng)控制器的view互為父子關(guān)系位迂,那么控制器最好也互為父子關(guān)系
三.分析
為什么要這樣設(shè)計(jì)访雪?
蘋果這樣設(shè)計(jì)一定是符合某個(gè)原理的,而這種原理一定是從實(shí)際生活中提煉出來的囤官,自己找個(gè)例子結(jié)合分析一下
生活中例子分析:組織一個(gè)車隊(duì)去拉一批貨物冬阳,首先要雇三個(gè)車,這是一個(gè)必要條件
第一種情況:司機(jī)把車交給你党饮,人跑了肝陪,貨拉不成
第二種情況:司機(jī)都在,不聽你指揮刑顺,全部跑去拉貨氯窍,擠成一團(tuán)
顯然這兩種情況都是不理想的,最合理的是司機(jī)全部聽你指揮蹲堂,服從你管理狼讨,這樣你讓那個(gè)去先拉,哪個(gè)后拉柒竞,秩序井然
注意:例子只是為了說明原理設(shè)計(jì)的合理性政供,不去深究,重點(diǎn)放到父子控制器上
父子控制器分析:
1.把一個(gè)tableViewController的view添加到普通的ViewController的view上朽基,但沒有設(shè)置父子控制器布隔,結(jié)果cell上不會(huì)顯示設(shè)置的測試內(nèi)容,稼虎,但是如果設(shè)置為父子控制器衅檀,cell上的內(nèi)容就可以顯示出來,所以必須要這樣做霎俩。
為什么不會(huì)顯示呢哀军?
經(jīng)過驗(yàn)證沉眶,它其中的cellForRowAtIndexPath方法調(diào)用了,測試內(nèi)容也可以打印出來杉适,但到了cell上就是沒有顯示
這里先通俗的理解為谎倔,tableViewController把view交給ViewController就不管了,就跑掉了猿推,實(shí)際上是控制器做為臨時(shí)變量被釋放掉了传藏,接受不到了內(nèi)容顯示的事件,點(diǎn)擊的事件彤守,這里有一個(gè)自己認(rèn)為的結(jié)論:內(nèi)容的顯示是一個(gè)事件
為什么要說內(nèi)容的顯示是一個(gè)事件呢毯侦?
這里的顯示指的是內(nèi)容的顯示,而不是視圖的顯示具垫,如果tableViewController侈离,作為一個(gè)根控制器,cell上面的內(nèi)容是可以正常顯示的筝蚕,但是一旦添加成別人的view卦碾,自己沒有成為子控制器,被釋放掉了起宽,里面的數(shù)據(jù)源方法也可以調(diào)用洲胖,但是就是不能顯示,說明了正常情況下坯沪,這個(gè)view只要出現(xiàn)在窗口上绿映,系統(tǒng)還會(huì)派發(fā)一個(gè)內(nèi)容顯示的事件,來觸發(fā)控制器中的內(nèi)容響應(yīng)方法腐晾,如果這個(gè)控制器被釋放掉了叉弦,當(dāng)然接受不到這個(gè)事件,也無法觸發(fā)這個(gè)內(nèi)容顯示的方法
再次重復(fù):
控制器的view是父子關(guān)系藻糖,那么控制器也應(yīng)為父子關(guān)系淹冰,當(dāng)把一個(gè)控制器的view添加為自己的subview時(shí),也要把控制器添加為自己的childViewController,這樣控制器才能夠正常接受內(nèi)容顯示事件巨柒,cell點(diǎn)擊事件樱拴,保證view內(nèi)部的數(shù)據(jù)和業(yè)務(wù)邏輯正常,完全正常的顯示
四.應(yīng)用場景:
1.標(biāo)題欄洋满,分類按鈕晶乔,分類顯示不同控制器的view,這樣子的應(yīng)用很多:如網(wǎng)易客戶端芦岂,新聞?lì)惪蛻舳吮窆伎梢允褂眠@樣的模型
這里分為兩種情況垫蛆,有些細(xì)節(jié)之處要注意:
1.1下方有scrollView:最好不要把多個(gè)控制器的view通過for循環(huán)一下都添加到scrollView上禽最,因?yàn)橹灰L問tableView控制器的view腺怯,就會(huì)加載viewDidLoad,加載完成后view要顯示就會(huì)觸發(fā)tableView控制器中的一系列方法川无,就會(huì)把所有cell數(shù)據(jù)都加載好呛占,不管你需要不需要,這樣子就有些浪費(fèi)了懦趋,而切換分類按鈕顯示的時(shí)候晾虑,由于下方存在scrollView,是通過手動(dòng)控制scrollView的轉(zhuǎn)動(dòng)來顯示的仅叫,應(yīng)該是切換到哪個(gè)再加載哪個(gè)view
1.2下方?jīng)]有scorllView:通過分類按鈕的tag為橋梁帜篇,找到子控制器,再從控制器中取出view诫咱,加上去笙隙,三步曲:設(shè)置一個(gè)屬性previousTag,第一步根據(jù)previousTag對(duì)應(yīng)的view移除坎缭,第二部根據(jù)現(xiàn)有的按鈕tag加上對(duì)應(yīng)的view竟痰,第三部把這個(gè)tag給了這個(gè)屬性,默認(rèn)顯示第一個(gè)按鈕對(duì)應(yīng)的view掏呼,那么previousTag = 0
2.側(cè)邊欄坏快,分類按鈕,分類view
注意:系統(tǒng)好多控件都是懶加載的憎夷,只要一訪問莽鸿,發(fā)現(xiàn)是空的,馬上就創(chuàng)建出來
如控制器的view拾给,按鈕中的子控件
需要進(jìn)一步研究的:關(guān)于IOS底層原理富拗,如果能夠知曉,可以起到事半功倍的效果鸣戴,不必要費(fèi)時(shí)想半天