0

I'm using this code (from this answer) along with a segmented control to switch between viewControllers in a container view, at the same time I'm using it to display another viewController in a second container view inside the same viewController. Because of this I had to comment out the original code removing the previous VC, in order for both container views to be embedded. (1) How can I still clean up the previous VCs? (2) Note that I'm also injecting dependencies into the children VCs, is this ok to do?

class ViewEmbedder {
    class func embed(parent:UIViewController,date: Date, container:UIView, child:UIViewController, previous:UIViewController?){

//        if let previous = previous {
//            print("previous = \(previous.description)")
////            if previous != ScoreAndStatsTableViewController {
////                //remove
////            }
//            
//            removeFromParent(vc: previous)
//        }
        child.willMove(toParentViewController: parent)

        if let hdtvc = child as? HealthDataTableViewController {
            hdtvc.startDate = date
        }
        if let idtvc = child as? IceDataTableViewController {
            idtvc.startDate = date
        }
        if let stvc = child as? ShiftTableViewController {
            stvc.startDate = date
        }




        parent.addChildViewController(child)
        container.addSubview(child.view)
        child.didMove(toParentViewController: parent)
        let w = container.frame.size.width;
        let h = container.frame.size.height;
        child.view.frame = CGRect(x: 0, y: 0, width: w, height: h)
    }

    class func removeFromParent(vc:UIViewController){
        vc.willMove(toParentViewController: nil)
        vc.view.removeFromSuperview()
        vc.removeFromParentViewController()
    }

    class func embed(withIdentifier id:String, startDate: Date, parent:UIViewController, container:UIView, completion:((UIViewController)->Void)? = nil){
        let vc = parent.storyboard!.instantiateViewController(withIdentifier: id)
        embed(
            parent: parent,
            date: startDate,
            container: container,
            child: vc,
            previous: parent.childViewControllers.first
        )
        completion?(vc)
    }
}

Usage:

class KingViewController: UIViewController {

    var startDate = Date() 

    @IBOutlet weak var topContainerView: UIView!

    @IBOutlet weak var bottomContainerView: UIView!


    @IBAction func controlDidChange(_ sender: UISegmentedControl) {

        switch sender.selectedSegmentIndex  {
        case 0:
            ViewEmbedder.embed(withIdentifier: "IceDataTableViewController", startDate: startDate, parent: self, container: bottomContainerView) { (bvc) in

            }
        case 1:
            ViewEmbedder.embed(withIdentifier: "HealthDataTableViewController",startDate: startDate, parent: self, container: bottomContainerView) { (bvc) in

            }
        case 2:
            ViewEmbedder.embed(withIdentifier: "ShiftTableViewController", startDate: startDate, parent: self, container: bottomContainerView) { (stvc) in

            }
GarySabo
  • 5,806
  • 5
  • 49
  • 124
  • You can use this third party library as it provides a lot of customization as well -> https://github.com/PageMenu/PageMenu – Muhammad Waqas Bhati Jan 25 '18 at 04:22
  • Thanks @MuhammadWaqasBhati it does look pretty great, but I try to avoid 3rd party dependencies as much as I can, just so I can control my own code base – GarySabo Jan 25 '18 at 04:24

1 Answers1

0

It feels like a bit of a hack but this is what I came up with as far as cleaning up existing VCs before embedding a new one: Still open to any more eloquent suggestions.

import Foundation
import UIKit

class ViewEmbedder {
    class func embed(id: String, parent:UIViewController,date: Date, container:UIView, child:UIViewController, previous:UIViewController?){

        let childVCArray = parent.childViewControllers
        for vc in childVCArray {
            print(vc.description)
            let vcID = vc.restorationIdentifier
            if vcID != id {
                vc.removeFromParentViewController()
            }

        }

        child.willMove(toParentViewController: parent)

        if let hdtvc = child as? HealthDataTableViewController {
            hdtvc.startDate = date
        }
        if let idtvc = child as? IceDataTableViewController {
            idtvc.startDate = date
        }
        if let stvc = child as? ShiftTableViewController {
            stvc.startDate = date
        }

        parent.addChildViewController(child)
        container.addSubview(child.view)
        child.didMove(toParentViewController: parent)
        let w = container.frame.size.width;
        let h = container.frame.size.height;
        child.view.frame = CGRect(x: 0, y: 0, width: w, height: h)
    }

    class func removeFromParent(vc:UIViewController){
        vc.willMove(toParentViewController: nil)
        vc.view.removeFromSuperview()
        vc.removeFromParentViewController()
    }

    class func embed(withIdentifier id:String, startDate: Date, parent:UIViewController, container:UIView, completion:((UIViewController)->Void)? = nil){
        let vc = parent.storyboard!.instantiateViewController(withIdentifier: id)
        embed(
            id: id,
            parent: parent,
            date: startDate,
            container: container,
            child: vc,
            previous: parent.childViewControllers.first
        )
        completion?(vc)
    }
}
GarySabo
  • 5,806
  • 5
  • 49
  • 124