Container View in iOS

Notice

This site has been moved to http://www.kodesnippets.com

You can find this tutorial here: Container View in iOS


Updated for iOS 9.1

Hello everyone!
I hope everyone would be doing great.

I googled for a long time but I couldn’t find any good tutorial for Container View, I read a tutorial where two Container Views were stacked over one another to achieve the required task, which is certainly not the proper way to do it.

Anyway, I am going to do a tutorial on Container View. So, Lets get started without wasting any further time.

Create a new project and drag a Container View along with two Buttons over a View Controller.
container

Drag a View Controller and connect Container View Controller with an Empty Segue to it. After that select the newly added View Controller open the Size Inspector and set the Simulated Size to Freeform and adjust the width and height of the controller according to the Container View Controller.
container2

Resulting (in my case):
Screen Shot 2015-08-09 at 2.59.34 am

Repeat the same step for a second View Controller.
Screen Shot 2015-08-09 at 2.59.56 am

Your Storyboard will more or less look like this:
identifiers

After that, add three classes of type UIViewController, i.e two for child view controllers(Let’s say FirstViewController.swift and SecondViewController.swift) and one for container view controller(ContainerViewController.swift), also add a class of type UIStoryboardSegue. Add all these classes to View Controllers and Empty Segues on storyboard, respectively.
When done adding classes, give identifiers to Embedded and Empty segues.

Open up your ViewController.swift class, create two action functions of the buttons that you added in the start, and paste the following code inside:

class ViewController: UIViewController {

 var containerView: ContainerViewController?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func second(sender: AnyObject) {
    containerView!.segueIdentifierReceivedFromParent("buttonTwo")
    }

    @IBAction func first(sender: AnyObject) {
    containerView!.segueIdentifierReceivedFromParent("buttonOne")
    }

   override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "container"{
        containerView = segue.destinationViewController as? ContainerViewController

        }
    }
}

In your ContainerViewController.swift, paste the following code:

class ContainerViewController: UIViewController {

    var vc : UIViewController!
    var segueIdentifier : String!
    var lastViewController: UIViewController!

    override func viewDidLoad() {
        super.viewDidLoad()
            segueIdentifierReceivedFromParent("buttonOne")

            }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func segueIdentifierReceivedFromParent(button: String){
        if button == "buttonOne"
        {

            self.segueIdentifier = "first"
            self.performSegueWithIdentifier(self.segueIdentifier, sender: nil)

        }
        else if button == "buttonTwo"
        {

            self.segueIdentifier = "second"
            self.performSegueWithIdentifier(self.segueIdentifier, sender: nil)
        }
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == segueIdentifier{
        //Avoids creation of a stack of view controllers
            if lastViewController != nil{
             lastViewController.view.removeFromSuperview()
            }
       //Adds View Controller to Container "first" or "second"
            vc = segue.destinationViewController as! UIViewController
            self.addChildViewController(vc)
            vc.view.frame = CGRect(x: 0,y: 0, width: self.view.frame.width,height: self.view.frame.height)
            self.view.addSubview(vc.view)
            vc.didMoveToParentViewController(self)
            lastViewController = vc

        }
    }
}

And in your Empty Segue class:

class Empty: UIStoryboardSegue{

    override func perform() {

    }
}

After that you’re good to go.

This project was built using Xcode 6.3.1 with SDK 8.3.
Here is a video of this project being run on a simulator.

I have uploaded this project on Github for reference.
Cheers!

30 thoughts on “Container View in iOS

    1. I don’t know if its the right way because only an official Apple developer can tell that. but what I can tell you is that its the only proper way you would find on internet. 🙂

      Like

  1. Hi, very nice tutorial. It’s working fine but I have added some textfield and buttons in first viewcontroller and second viewcontroller. How can i create action for these buttons? i am not able create action for these button. Please help me buddy.

    Like

    1. Hello Ramachandran, I tried and I wasn’t able to create an action in the first attempt too. I know it sounds weird but in your first view controller create write a function lets say @IBAction func testButton(sender: UIButton){}. After that link your button to this function. it will create a connection. After that try control dragging your button in the class again it will work. It worked for me. 🙂
      If you still have a question you can contact me at: aaqibhussain@kodesnippets.com
      Peace!

      Like

  2. Hi, many thanks for that and for the Objctive-C version. Loved it. I hope you don’t mind my question but Would this approach be suitable if i want to visualise both the First and Second View at the same time, but stacked on top of each other in the screen? May be with a Stacked layout?

    Many Thanks,
    GC

    Like

  3. Aaqib Hussain I discover my mistake in my own implementation of ContainerController I first set up my view controller and later move it to didMoveToParentViewController, but the correct way is first didMoveToParentViewController and later fill my view controller.

    Like

  4. I have a question, is there a way to not instantiate a new view controller every time i change views? For example lets say i change from First View Controller to the second view controller, can i retrieve the first view instead of creating a new instance of it? For example if i download a json in the first view, it will download again if i change views, there is a way to avoid that?

    Great tutorial by the way.

    Like

  5. I have followed 6 other posts and tutorials and tried 5 other Git Hub projects, all to fail. THIS ONE IS PERFECT. You perfectly execute passing data between container views. This has saved me from banging my head against the desk. Thank you !

    Like

Leave a Comment