Thursday, July 18, 2019

Embedding a view controller's root view in another view controller's view

We can add a view controller's root view to another view controller's view for reusability purpose.


We can programmatically add a view controller's root view to a subview of another view controller as following:

public class ThemesViewController : UIViewController {

 @IBOutlet weak var previewView: UIStackView!
 var vcMain:ViewController!

 ...

 public override func viewDidLoad() {
   vcMain = storyboard?.instantiateViewController(withIdentifier: "vcMain") as! ViewController
 } 
 
 public override func viewWillAppear(_ animated: Bool) {
                // The system does not wait until each view in the hierarchy
                // has updated its layout before calling the viewWillAppear() method
                // so some subviews still have incorrect bounds
                // and will change in viewDidAppear() method.
                // Calling layoutIfNeeded() method forces the previewView to
                // update its layout immediately so we get the correct bounds here.
                previewView.layoutIfNeeded()   
        
                self.addChildViewController(vcMain)
  previewView.addSubview((vcMain.view)!)
  vcMain.didMove(toParentViewController: self)
 }
}
    

The addChildViewController() method calls the willMove(toParentViewController:) of the child view controller for us so we can override the method and do more things if needed.

The didMove(toParentViewController: self) method of the child view controller have to be called after the child view controller's root view has been added to the parent view controller's view and any necessary constraints between the views have been defined. This method gives the chance to the child view controller to perform any actions if needed, responding to the change in view ownership (by overriding the method). Note that my project still worked correctly even if I didn't call didMove(toParentViewController:) method.

In my case, the size and position of the previewView were already set in the Interface Builder so I don't have to programmatically create constraints for the previewView, after calling previewView.addSubview((vcMain.view)!) as mentioned here.


No comments:

Post a Comment