Search code examples
iosswiftuiviewcontrollerxcode-storyboarduicontainerview

Switch Between Child View Controllers


I have a view controller that contains multiple container views, we will call it HomeViewController. I declare these container views (childViewControllers) as so (each one is a Container View with its own embeded viewController:

private lazy var startContactViewController: StartContactViewController = {
    //Load Storyboard
    let storybaord = UIStoryboard(name: "Main", bundle: Bundle.main)

    //Instantiate View Controller
    var viewController = storyboard?.instantiateViewController(withIdentifier: "StartContact") as! StartContactViewController

    //Add View Controller as Child View Controller
    self.add(asChildViewController: viewController)

    return viewController
}()

private lazy var stopContactViewController: StopContactViewController = {
    //Load Storyboard
    let storybaord = UIStoryboard(name: "Main", bundle: Bundle.main)

    //Instantiate View Controller
    var viewController = storyboard?.instantiateViewController(withIdentifier: "StopContact") as! StopContactViewController

    //Add View Controller as Child View Controller
    self.add(asChildViewController: viewController)

    return viewController
}()

private lazy var startDayViewController: StartDayViewController = {
    //Load Storyboard
    let storybaord = UIStoryboard(name: "Main", bundle: Bundle.main)

    //Instantiate View Controller
    var viewController = storyboard?.instantiateViewController(withIdentifier: "StartDay") as! StartDayViewController

    //Add View Controller as Child View Controller
    self.add(asChildViewController: viewController)

    return viewController
}()

private lazy var loadingViewController: LoadingViewController = {
    //Load Storyboard
    let storybaord = UIStoryboard(name: "Main", bundle: Bundle.main)

    //Instantiate View Controller
    var viewController = storyboard?.instantiateViewController(withIdentifier: "loading") as! LoadingViewController

    //Add View Controller as Child View Controller
    self.add(asChildViewController: viewController)

    return viewController
}()

I then have these 2 functions to add and remove the childViewControllers:

func add(asChildViewController viewController: UIViewController) {
    //Add Child View Controller
    addChildViewController(viewController)

    //Add Child View as Subview
    view.addSubview(viewController.view)

    //Configure Child View
    viewController.view.frame = view.bounds
    viewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]

    //Notify Child View Controller
    viewController.didMove(toParentViewController: self)
}

func remove(asChildViewController viewController: UIViewController) {
    // Notify Child View Controller
    viewController.willMove(toParentViewController: nil)

    // Remove Child View From Superview
    viewController.view.removeFromSuperview()

    // Notify Child View Controller
    viewController.removeFromParentViewController()
}

When my app first loads the StartDayViewController is presented. Within this view controller their is a button. When the users presses that button I would like the StartDayViewController to be removed and the StartContactViewController to be presented. How can I achieve this from the StartDayViewController?

I have also included a picture of the storyboard. Storyboard image


Solution

  • You can do it using protocol

    protocol StartVcProtocol {
             func startButtonPressed()
    }
    

    Let HomeViewController implement it

    extension HomeViewController: StartVcProtocol {
        func startButtonPressed() {
            // start button pressed -- do your remove and add stuff here
        }
    }
    

    Now in StartVc

    class StartVc: UIViewController {
    
        var delegate: StartVcProtocol?
    
    
     //inside you start button iBaction
    delegate?.startButtonPressed()
    
    }
    

    Then when lazy initializing the StartVc

    viewController.delegate = self
    

    Hope you get all the pieces .