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:
方法;因此
- 一個(gè)容器的子視圖控制器過(guò)渡到另一個(gè)子類控制器完成之后,會(huì)調(diào)用
didMoveToParentViewController:
方法 - 沒(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):
- 當(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)用了。
- 當(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
方法的使用
這兩個(gè)方法用在子試圖控制器交換的時(shí)候調(diào)用验夯!即調(diào)用
transitionFromViewController
方法時(shí)猖吴,調(diào)用。當(dāng)調(diào)用
willMoveToParentViewController
方法或didMoveToParentViewController
方法時(shí)挥转,要注意他們的參數(shù)使用:
- 當(dāng)某個(gè)子視圖控制器將從父視圖控制器中刪除時(shí)海蔽,
parent
參數(shù)為nil
。
[將被刪除的子試圖控制器 willMoveToParentViewController:nil];
- 當(dāng)某個(gè)子試圖控制器將加入到父視圖控制器時(shí)绑谣,
parent
參數(shù)為父視圖控制器党窜。
[將被加入的子視圖控制器 didMoveToParentViewController:父視圖控制器];
- 無(wú)需調(diào)用[子視圖控制器
willMoveToParentViewController:
父視圖控制器]方法。因?yàn)槲覀冋{(diào)用[父視圖控制器 addChildViewController:子視圖控制器]
時(shí)借宵,已經(jīng)默認(rèn)調(diào)用了幌衣。
只需要在transitionFromViewController
方法后,調(diào)用
[子視圖控制器didMoveToParentViewController:父視圖控制器]
- 無(wú)需調(diào)用
[子視圖控制器 didMoveToParentViewController:父視圖控制器]
方法壤玫。因?yàn)槲覀冋{(diào)用
[子視圖控制器 removeFromParentViewController]
時(shí)豁护,已經(jīng)默認(rèn)調(diào)用了。
只需要在transitionFromViewController
方法之前調(diào)用:
[子視圖控制器 willMoveToParentViewController:nil]