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

时间:2015-04-17 12:17:35

标签: ios swift uiviewcontroller uitabbarcontroller uicontainerview

我在我的应用程序中创建了一个容器视图。当容器视图中加载 UITableviewCell 上的用户选项卡和其他 UIViewController 时,容器视图会加载其他 UIViewController 。我尝试通过在其他ViewController类上插入日志消息进行测试,并在每次调用 viewDidLoad ViewDidAppear 方法时发现表明这些类每次都在单元格选项卡上进行实例化。

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

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

然而,我按照以下教程创建了容器视图控制器: https://github.com/codepath/ios_guides/wiki/Container-View-Controllers-Quickstart

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")


        }




    }


}

2 个答案:

答案 0 :(得分:1)

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

基本上你需要做的是:

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

我在很多地方使用这个程序。

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

答案 1 :(得分:1)

在分配后将非活动视图控制器缓存在数组中,并且只调用一次viewDidLoad方法。

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