iOS - 进阶之正确添加子控制器的方法

iOS - 进阶之正确添加子控制器的方法_第1张图片
mountain-man.jpg

1. 常见的业务场景

在iOS开发过程中,有很多时候,开发者需要将ViewController对象a添加到另一个ViewController对象b中,此时称a为b的childViewController,如下代码所示,

class BViewController: UIViewController {
  override func viewDidLoad() {
    let aVC = AViewController()
    self.view.addSubview(aVC.view)
    self.addChildViewController(aVC)
  }
}

这样的写法存在一个潜在的问题,那就是当添加多个子控制器到父控制器,例如网易新闻客户端的首页,在不同的子控制器切换的时候,子控制器的-viewWillAppear不执行。究其原因,当我们使用-addSubview-addChildViewController添加子控制器时,是不正确或不完整的添加方式,因为-addSubview-addChildViewController能保证子控制器的-viewDidLoad-viewWillAppear执行一次,并不能保证-viewWillAppear在子控制器展示的时候都执行。

2. 解决子控制器-viewWillAppear不执行的问题

class BViewController: UIViewController {
  override func viewDidLoad() {
    let aVC = AViewController()
    aVC.beginAppearanceTransition(true, animated: false)
    self.view.addSubview(aVC.view)
    childVC.endAppearanceTransition()
    childVC.didMove(toParentViewController: self)
  }
}

3. 代码优化

为了不重复造轮子,建议将该功能封装起来,方便以后调用。在swift中,将上述代码封装为UIViewController的extension方法,是一个不错的选择,如下代码所示,


import UIKit
extension UIViewController {
    func addChildViewController(_ childVC: UIViewController, toView: UIView) {
        childVC.beginAppearanceTransition(true, animated: false)
        toView.addSubview(childVC.view)
        childVC.endAppearanceTransition()
        childVC.didMove(toParentViewController: self)
    }
}

当开发者需要添加子视图控制器到父控制器时,即可简单调用,如下代码,

class BViewController: UIViewController {
  override func viewDidLoad() {
    let aVC = AViewController()
    self.addChildViewController(aVC, toView: self.view)
  }
}

这样,父控制器就合理有效地管理子控制器的生命周期,当多个子控制器相互切换时,对应的子控制器的生命周期方法会有效执行。

你可能感兴趣的:(iOS - 进阶之正确添加子控制器的方法)