幾年前就從網(wǎng)上抄襲過addChildViewController的用法,但沒花過心思去理解它。而且锨用,很多抄襲來的代碼耸峭,無法理解為什么要那么寫!(因為有些本來就寫得爛蝉稳,也誤導了自己..)
今天又重新搞了一遍抒蚜,(以前很少用,所以耦合度有點高..)耘戚,參考其官方注釋和其他人的代碼嗡髓。
先看幾個屬性、方法:
- 子控制器數(shù)組收津,不包含任何當前展示的子控制器
open var childViewControllers: [UIViewController] { get }
- 如果該子控制器有另一個父控制器饿这,會先通過執(zhí)行removeFromParentViewController方法把該子控制器
從其當前父控制器移除。如果重載該方法朋截,必須調(diào)用super方法蛹稍。
open func addChildViewController(_ childController: UIViewController)
- 把自身從父控制器的childViewControllers數(shù)組中移除。如果重載部服,必須調(diào)用super方法唆姐。
open func removeFromParentViewController()
- 該方法可用于切換兄弟控制器。方法調(diào)用者是它們共同的父控制器廓八。(用 [UIViewController addChildViewController:] 建立父子關(guān)系)
該方法將把【‘toViewController’的view】添加到【‘fromViewController’的view的父視圖view】上奉芦;
當切換完成后赵抢,【‘fromViewController’的view】將從其父視圖上移除。声功,...烦却,
該方法調(diào)用者不能是iOS容器類控制器及其子類(tabbar,navigation controller等)...。
open func transition(from fromViewController: UIViewController, to toViewController: UIViewController,
duration: TimeInterval, options: UIViewAnimationOptions = [],
animations: (() -> Swift.Void)?,
completion: ((Bool) -> Swift.Void)? = nil)
根據(jù)這幾個方法說明先巴,我認為其爵,childViewControllers是配合addChildViewController一起用的,當然
內(nèi)部肯定還有remove相關(guān)的操作伸蚯,暫時不用關(guān)心摩渺。addChildViewController沒有任何特別的操作,就是往數(shù)組里添加元素剂邮,以此來確認雙方父子關(guān)系摇幻。父控制器則通過childViewControllers辨認哪些是自己的兒子,兒子們相互間就是兄弟挥萌。
關(guān)鍵方法transition(from,to,duration,options,animations,completion)則是用于兄弟控制器的切換绰姻。有些人在每次調(diào)用切換方法之前,還調(diào)用addChildViewController引瀑,完了還調(diào)用removeFromParentViewController狂芋。純粹是脫褲子放屁!完全沒必要伤疙,因為transition方法并不會移除子控制器银酗。
所以正確的寫法應(yīng)該是:
- 在父控制器中:
1.添加子控制器
func addChildVCs() {
//直接導致firstVC執(zhí)行willMove(toParentViewController parent: UIViewController?)
self.addChildViewController(firstVC)
//直接導致secondVC執(zhí)行willMove(toParentViewController parent: UIViewController?)
self.addChildViewController(secondVC)
firstVC.view.frame = self.view.bounds
self.view.addSubview(firstVC.view)
firstVC.didMove(toParentViewController: self) //手動調(diào)用
currentVC = localPackageVC
}
2.子控制器間的切換(不需要再寫addChildViewController!也不要寫oldVC.removeFromParentViewController())
func changeControllerFrom(oldVC: UIViewController, to newVC: UIViewController) {
//oldVC.willMove(toParentViewController: nil) //手動調(diào)用
//newVC.willMove(toParentViewController: self) //手動調(diào)用
newVC.view.frame = self.view.bounds
self.transition(from: oldVC, to: newVC, duration: 0.5, options: UIViewAnimationOptions.transitionCrossDissolve, animations: {}, completion: { (isfinished) in
if isfinished {
oldVC.didMove(toParentViewController: nil) //手動調(diào)用
newVC.didMove(toParentViewController: self) //手動調(diào)用
self.currentVC = newVC
}
})
- 子控制器中:
監(jiān)聽切換狀態(tài):
//移除徒像,則parent == nil
override func willMove(toParentViewController parent: UIViewController?) {
debugPrint("will move..parent=" + ((parent == nil) ? "nil" : "parent"))
}
//移除黍特,則parent == nil
override func didMove(toParentViewController parent: UIViewController?) {
debugPrint("did move..parent=" + ((parent == nil) ? "nil" : "parent"))
}