筆記:iOS中addChildViewController的使用

iOS早在iOS5的時候為了解耦、更加清晰的處理頁面View的邏輯,UIViewController提供了addChildViewController方法,將ViewController作為容器處理視圖控制器的切換,將比較復(fù)雜的UI使用子ViewController來管理。

iOS5.0之前只能在ViewControllerview中不斷的通過addSubView添加subViewVCview視圖層級中。這樣使得主ViewController中的內(nèi)容越來越混亂,代碼越來越多,subView的管理越來越困難。
iOS5.0之后按照MVC的原則,每個ViewController只需要管理一個view視圖層次結(jié)構(gòu),因此我們可以使用childViewController來拆分開發(fā)中比較復(fù)雜的View。并且此時的childViewController擁有了與父ViewController同步的聲明周期。

項目中使用:

在我們項目的APP首頁的實現(xiàn)中使用到了,首頁內(nèi)容展示位推薦分類菜單,以及每個菜單下的內(nèi)容展示,不同的分類下的內(nèi)容view展示的UI多樣化。

相關(guān)方法:

///子視圖控制器數(shù)組
@property(nonatomic,readonly) NSArray *childViewControllers

///向父VC中添加子VC
- (void)addChildViewController:(UIViewController *)childController

///將子VC從父VC中移除
- (void) removeFromParentViewController

///fromViewController 當(dāng)前顯示在父視圖控制器中的子視圖控制器
///toViewController 將要顯示的姿勢圖控制器
///duration 動畫時間
/// options 動畫效果(漸變,從下往上等等,具體查看API)
///animations 轉(zhuǎn)換過程中得動畫
///completion 轉(zhuǎn)換完成
- (void)transitionFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^ __nullable)(void))animations completion:(void (^ __nullable)(BOOL finished))completion

///當(dāng)向父VC添加子VC之后,該方法會自動調(diào)用;
- (void)willMoveToParentViewController:(UIViewController *)parent

///從父VC移除子VC之后,該方法會自動調(diào)用
- (void)didMoveToParentViewController:(UIViewController *)parent

如何使用?:

  • 如果在view上添加的只是簡單的控件的話,那么使用addSubView添加到父ViewController上;
  • 如果子視圖是比較復(fù)雜的視圖集合,功能豐富,就選擇使用addChildViewController來添加新的子ViewController,但也需要通過addSubview將子ViewControllerview添加到父視圖的視圖層級中;
  • iOS5之后使用addChildViewController時的原則,我們在使用addSubview的時候,同時調(diào)用addChildViewController方法將subView對應(yīng)的viewController也加到當(dāng)前viewController的管理中;
  • 對于那些不需要顯示的subView,只需通過addChildViewControllersubVC添加到父控制器中,需要顯示時再調(diào)用transitionFromViewController方法將其顯示出來;
  • 當(dāng)收到系統(tǒng)的 Memory Warning 的時候,系統(tǒng)也會自動把當(dāng)前沒有顯示的 subview 銷毀掉 掉,以節(jié)省內(nèi)存;
  • 優(yōu)點:
  1. 使頁面邏輯更加清晰明了,遵循MVC模式,每個View對應(yīng)相應(yīng)的ViewController;
  2. 當(dāng)存在不需顯示的view時,將不會被加載,減少內(nèi)尺使用;
  3. 當(dāng)收到內(nèi)存警告時,會將沒有加載出的view率先釋放,優(yōu)化了程序的內(nèi)存釋放機制;

系統(tǒng)方法解釋:

  • addChildViewController

[A父視圖控制器 addChildViewController:B子視圖控制器]在視圖控制器A中添加了子視圖控制器B.調(diào)用這個方法時如果子視圖控制器已經(jīng)有父視圖控制器了,那么調(diào)用該方法會先把子視圖控制器從之前的父視圖控制器中移除,然后再添加到當(dāng)前的視圖控制器上作為子視圖控制器。

注意:調(diào)用addChildViewController后會自動調(diào)用willMoveToParentViewController:superVC方法;

  • removeFromParentViewController

將子視圖控制器從父視圖控制器中移除,移除之后將自動調(diào)用didMoveToParentViewController

注意:調(diào)用removeFromParentViewControlle后會調(diào)用didMoveToParentViewController:nil方法

  • willMoveToParentViewController

當(dāng)一個視圖控制器從視圖控制器容器中被添加或者被刪除之前,該方法被調(diào)用parent:父視圖控制器,如果沒有父視圖控制器,將為nil;當(dāng)調(diào)用removeFromParentViewController方法是必須先手動調(diào)用該方法,且parent參數(shù)為nil。

  • didMoveToParentViewController

當(dāng)從一個視圖控制容器中添加或者移除viewController后,該方法被調(diào)用;當(dāng)調(diào)用addChildViewController方法時必須手動調(diào)用該方法,且parent參數(shù)為父控制器。

代碼展示:

  • 添加子VC
//自動調(diào)用,可以省略 
//[childVC willMoveToParentViewController: superVC];
[superVC addChildViewController:childVC];
[superVC.view addSubview:childVC.view];
[childVC didMoveToParentViewController:superVC];
  • 刪除子VC
[childVC willMoveToParentViewController];
[childVC removeFromParentViewController];
//自動調(diào)用,可以省略
//[childVC didMoveToParentViewController:nil]; 
  • 切換子VC
[self addChildViewController:newController];
[self transitionFromViewController:oldController toViewController:newController duration:1.5f options:UIViewAnimationOptionCurveEaseOut animations:^{
        
} completion:^(BOOL finished) {
    if (finished) {
        [newController didMoveToParentViewController:self];
        [oldController willMoveToParentViewController:nil];
        [oldController removeFromParentViewController];
        self.currentVC = newController;
    }
    else{
        self.currentVC = oldController;
    }
}];

總結(jié):

  1. addChildViewController向父視圖控制器中添加子視圖控制器時,添加之后自動調(diào)用willMoveToParentViewController,需要手動調(diào)用didMoveToParentViewController
  2. removeFromParentViewController將子視圖控制器從父視圖控制器中移除,移除之后自動調(diào)用didMoveToParentViewController: nil參數(shù)為nil,需要在移除前手動調(diào)用willMoveToParentViewController;
  3. transitionFromViewController:toViewController在調(diào)用這個方法之前先調(diào)用[fromViewController willMoveToParentViewController:nil]然后在completion后調(diào)用[toViewController didMoveToParentViewController:self]方法;
  4. 在切換子視圖控制器顯示的時候需要保證切換的子視圖控制器已經(jīng)被添加到父視圖控制器中;
  5. 當(dāng)某個子視圖控制器將從父視圖控制器中刪除時,parent參數(shù)為nil,即:[將被刪除的VC willMoveToParentViewController:nil];
  6. 當(dāng)某個子試圖控制器將加入到父視圖控制器時,parent參數(shù)為父視圖控制器,即:[將被加入的VC didMoveToParentViewController:superVC];

參考文獻

  1. https://blog.csdn.net/yongyinmg/article/details/40619727
  2. iOS之ViewController容器篇
  3. 學(xué)習(xí)筆記:addChildViewController
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容