如何使ViewController的viewDidLoad方法只调用一次?

我在我的应用程序中创build了一个Container View 。 当UITableviewCell和其他UIViewController的用户选项卡被加载到容器视图中时,容器视图加载其他的UIViewController 。 我试图通过在其他ViewController类插入日志消息进行testing,并发现每次viewDidLoadViewDidAppear方法被调用哪些状态,这些类每次在单元格选项卡上实例化。

但是,当在苹果文档上研究容器视图时https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html

我发现UITabBarController也实现了ContainerView,并在数组中pipe理它的UIViewController 。 我试着检查日志消息,发现viewDidLoad方法只被调用一次,当我们第二次访问该选项卡时,只有viewDidAppear被调用。 所以我真的很想知道这背后的事情是什么。 他们使用UnWind赛格(我猜不是)。

不过,我按照以下教程创build容器视图控制器: https : //github.com/codepath/ios_guides/wiki/Container-View-Controllers-Quickstart as

class ViewController: UIViewController { @IBOutlet weak var contentView: UIView! var activeViewController : UIViewController? { didSet{ removeInactiveViewController(oldValue) updateActiveViewController() } } var cellTxtArrs = ["FIRST","SECOND","THIRD"] override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. var tblView : UITableView = UITableView() tblView.frame = CGRectMake(0, 20, 300 ,100) tblView.separatorColor = UIColor.clearColor() tblView.scrollEnabled = false tblView.rowHeight = (30) self.view.addSubview(tblView) tblView.delegate = self tblView.dataSource = self tblView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "myCell") } func removeInactiveViewController(inactiveViewController:UIViewController?){ if let inActiveVC = inactiveViewController{ inActiveVC.willMoveToParentViewController(nil) inActiveVC.view.removeFromSuperview() inActiveVC.removeFromParentViewController() } } func updateActiveViewController(){ if let activeVC = activeViewController{ //not necessary addChildViewController(activeVC) activeVC.view.frame = contentView.bounds contentView.addSubview(activeVC.view) activeVC.didMoveToParentViewController(self) } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } extension ViewController : UITableViewDataSource , UITableViewDelegate{ //MARK: table view data source methods func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { // cell.textLabel?.font = UIFont(name: label.font.fontName, size: 22) var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("myCell") as! UITableViewCell cell.backgroundColor = UIColor(red: 0.000, green: 0.400, blue: 0.404, alpha: 1.00) cell.selectionStyle = UITableViewCellSelectionStyle.None cell.textLabel?.text = self.cellTxtArrs[indexPath.row] cell.textLabel?.textAlignment = NSTextAlignment.Left cell.textLabel?.textColor = UIColor.whiteColor() return cell } func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.cellTxtArrs.count } //MARK: - table view delegate methods func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { var row = indexPath.row switch row { case 0: let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) let firstVC = storyboard.instantiateViewControllerWithIdentifier("firstVC") as! FirstViewController activeViewController = firstVC case 1: var storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) let secondVC = storyboard.instantiateViewControllerWithIdentifier("secondVC") as! SecondViewController activeViewController = secondVC case 2: let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) let thirdVC = storyboard.instantiateViewControllerWithIdentifier("thirdVC") as! ThirdViewController activeViewController = thirdVC default: println("no index") } } } 

标签栏控制器有一个子控制器的数组,它们之间切换时保持不变。

基本上你需要做的是:

  • 创build一个容器来容纳子控制器(一个数组)
  • 如果数组不存在,则将控制器添加到数组中
  • 如果存在,则重新使用数组中的控制器

我在相当多的地方使用这个程序。

注意这也适用于在内容视图中有导航控制器,但导航堆栈也将持续,这可能不是一个理想的结果。 例如,如果您有3个选项卡,并且第一个选项卡导航到第二个视图控制器,它将保留在第二个视图控制器上,即使切换到第三个选项卡并返回到第一个选项卡。

在分配后caching非活动的视图控制器在一个数组中,你只会调用他们的viewDidLoad方法一次。

现在viewDidLoad被调用,因为你每次都分配一个新的视图控制器。