iOS5.0 後 UIViewController新增:willMoveToParentViewController和didMoveToParentViewController
在ios 5.0以前,我們在一個UIViewController中這樣組織相關的UIView
在以前,一個UIViewController的View可能有很多小的子view。這些子view很多時候被蓋在最後,我們在最外層ViewController的viewDidLoad方法中,用addSubview增加了大量的子view。這些子view大多數不會一直處於界面上,只是在某些情況下才會出現,例如登陸失敗的提示view,上傳附件成功的提示view,網絡失敗的提示view等。但是雖然這些view很少出現,但是我們卻常常一直把它們放在內存中。另外,當收到內存警告時,我們只能自己手工把這些view從super view中去掉。
在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
這樣,就能夠將一個頁面中的UIViewController控制起來,而不是混亂的共用一個UIViewController,最重要的是,編程習慣的革命:降低了功能的耦合度!
寫這篇博客,僅僅是講以上5個方法!僅此而已。因爲當我在百度或者谷歌中,輸入以上5個方法的名字後,查出來的,並沒有告訴這5個方法起到如何的作用?如何使用?
所以,我僅僅是想從API角度來談一談,這5個方法。
先搞清楚一個今天提到的概念:
[父視圖控制器 addChildViewController:子視圖控制器]
;
在此,圖控制器A添加了另一個圖控制器B,那麼A充當父視圖控制器,B充當子視圖控制器。父視圖控制器充當了視圖控制器容器的角色。
addChildViewController方法:
- (void)addChildViewController:(UIViewController *)childController
向視圖控制器容器中添加子視圖控制器
childController:子視圖控制器
當要添加的子視圖控制器已經包含在視圖控制器容器中,那麼,相當於先從父視圖控制器中刪除,然後重新添加到父視圖控制器中。
removeFromParentViewController 方法
(void)removeFromParentViewController
從父視圖控制器中刪除。
transitionFromViewController 方法
- (void)transitionFromViewController:(UIViewController *)fromViewControllertoViewController:(UIViewController *)toViewController duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion
交換兩個子視圖控制器的位置(由於添加的順序不同,所以子試圖控制器在父視圖控制器中存在層次關係)
fromViewController:當前顯示的子試圖控制器,將被替換爲非顯示狀態
toViewController:將要顯示的子視圖控制器
duration:交換動畫持續的時間,單位秒
options:動畫的方式
animations:動畫Block
completion:完成後執行的Block
willMoveToParentViewController 方法
(void)willMoveToParentViewController:(UIViewController *)parent
當一個視圖控制器從視圖控制器容器中被添加或者被刪除之前,該方法被調用
parent:父視圖控制器,如果沒有父視圖控制器,將爲nil
注意點:
1. 當我們向我們的視圖控制器容器中調用removeFromParentViewController方法時,必須要先調用該方法,且parent參數爲nil:
- [將要刪除的視圖控制器 willMoveToParentViewController:nil];
2. 當我們調用addChildViewController方法時,在添加子視圖控制器之前將自動調用該方法。所以,就不需要我們顯示調用了。
didMoveToParentViewController
方法
- (void)didMoveToParentViewController:(UIViewController *)parent
當從一個視圖控制容器中添加或者移除viewController後,該方法被調用。
parent:父視圖控制器,如果沒有父視圖控制器,將爲nil
3. 當我們向我們的視圖控制器容器(就是父視圖控制器,它調用addChildViewController方法加入子視圖控制器,它就成爲了視圖控制器的容器)中添加(或者刪除)子視圖控制器後,必須調用該方法,告訴iOS,已經完成添加(或刪除)子控制器的操作。
removeFromParentViewController 方法會自動調用了該方法,所以,刪除子控制器後,不需要在顯示的調用該方法了。
其實,這幾個方法中的API說明,看的還懂。
最後:
關於willMoveToParentViewController
方法和didMoveToParentViewController
方法的使用
1. 這兩個方法用在子試圖控制器交換的時候調用!即調用transitionFromViewController
方法時,調用。
2. 當調用willMoveToParentViewController
方法或didMoveToParentViewController
方法時,要注意他們的參數使用:
當某個子視圖控制器將從父視圖控制器中刪除時,parent參數爲nil。
即:[將被刪除的子試圖控制器 willMoveToParentViewController:nil]
;
當某個子試圖控制器將加入到父視圖控制器時,parent參數爲父視圖控制器。
即:[將被加入的子視圖控制器 didMoveToParentViewController:父視圖控制器]
;
3. 無需調用[子視圖控制器 willMoveToParentViewController:父視圖控制器]方法。因爲我們調用[父視圖控制器 addChildViewController:子視圖控制器]時,已經默認調用了。
只需要在transitionFromViewController方法後,調用[子視圖控制器didMoveToParentViewController:父視圖控制器]
;
4. 無需調用[子視圖控制器didMoveToParentViewController:
父視圖控制器]方法。因爲我們調用
[子視圖控制器 removeFromParentViewController]時,已經默認調用了。
只需要在transitionFromViewController
方法之前調用:[子視圖控制器 willMoveToParentViewController:nil]
。