iosswiftxcodeuiviewcontrolleruicontainerview

using didSet to pass value to container view


I can successfully use didSet on the main UIViewController and it prints the value.

var viewModel: ViewModel {
    didSet {
       label.text = viewModel.getData()
       print(viewModel.getData())
    }
}

This code works I can retreive the data so there is no problem with retrieving data.

The problem is passing this data to a Container UIView which is embedded in my main UIViewController. I have just used a IBOutlet childLabel in my container's ViewController and I wanted to print the value that is being printed in my main UIView to my Container UIView. I have declared my Container UIViewController in my main UIViewController as var VC: DetailViewController?

I used this code it prints the value but doesn't show up on the simulator. I want to know what is my mistake :(

var viewModel: ViewModel {
    didSet {
         if let dvc = VC {
            dvc.childLabel.text = viewModel.getData()
         }
     print(viewModel.getData())
    }
}

Solution

  • First, use better (more descriptive) variable names -- it will save you many headaches down the road:

    // bad!
    var VC: DetailViewController?
    
    // better
    var detailVC: DetailViewController?
    

    Second, you are declaring that var as optional (by using "?"). If you set a breakpoint in your code and step through, you will see that this line:

    if let dvc = VC {
    

    will be false, and the next line won't execute.

    You need to assign the Container ViewController to that variable. When using a UIContainerView in Storyboard, an "embed" segue is automatically created. So, you can get a reference to that controller in prepare for segue:

    class MainViewController: UIViewController {
    
        // to hold a reference to the Container View embedded controller   
        var detailVC: DetailViewController?
    
        var viewModel: ViewModel {
            didSet {
                // unwrap the optional
                if let dvc = self.detailVC {
                    print("we have a valid reference to Detail View Controller")
                    dvc.childLabel.text = viewModel.getData()
                }
                print(viewModel.getData())
            }
        }
    
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if let destVC = segue.destination as? DetailViewController {
                self.detailVC = destVC
            }
        }
    
        // ... the rest of your view controller code...
    }