25

I want to embed a UIViewController inside a UIView. I want to create this programmatically. I have created the UIViewController inside the storyboard.

My code to create a empty UIView:

let myNewView=UIView(frame: CGRect(x: (0 + screenHeight / 2), y: leftView.frame.origin.y, width: screenHeight / 2, height: leftView.frame.height))
myNewView.backgroundColor=UIColor.lightGray

self.view.addSubview(myNewView)

And the code to append the UIViewController to the view:

let storyboard = UIStoryboard(name: "Main", bundle: nil)
var controller: UIViewController = storyboard.instantiateViewController(withIdentifier: "testView") as UIViewController
myNewView.addSubview(controller.view)

This displays the view inside my UIView, but not at the correct way. The UIView is in this case 512 pixels wide. While the (embeded) UIViewcontroller thinks that is is 1024 pixels wide (the full screen width).

How can I fix it that the embeded view gets the width and height from its parent (the UIView)?

Tamás Sengel
  • 55,884
  • 29
  • 169
  • 223
da1lbi3
  • 4,369
  • 6
  • 31
  • 65
  • What you are doing is totally wrong. You cannot simply add a view controller's view to your interface that way. (As for the size, providing a `frame` for the added view is up to you. But your view will not work correctly in any case.) – matt Mar 31 '17 at 22:17
  • @matt What is a good way of doing this? – da1lbi3 Mar 31 '17 at 22:21

3 Answers3

59

As others said you can't embed a viewcontroller view inside a view. What you can do is embed a ViewController inside another ViewController as a ChildViewController.

Try replacing your newView code with:

let storyboard = UIStoryboard(name: "Main", bundle: nil)
var controller: UIViewController = storyboard.instantiateViewController(withIdentifier: "testView") as UIViewController

//add as a childviewcontroller
 addChildViewController(controller)

 // Add the child's View as a subview
 self.view.addSubview(controller.view)
 controller.view.frame = view.bounds
 controller.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]

 // tell the childviewcontroller it's contained in it's parent
  controller.didMove(toParentViewController: self)

EDIT
To change how and where the childviewcontroller appears, simply update its frame. for example to make it half the height and anchored to the bottom:

controller.view.frame = CGRect(x: 0, y: view.center.y, width: view.size.width, height: view.size.height * 0.5) 
Kozmotronik
  • 2,080
  • 3
  • 10
  • 25
ahbou
  • 4,710
  • 23
  • 36
  • 1
    But how can I add the new view controller at an certain position? For example only on the half of the screen? – da1lbi3 Apr 01 '17 at 10:15
  • 1
    @da1lbi3 you can change origin and size by updating the frame. See my edited answer – ahbou Apr 01 '17 at 20:38
15

Updated to the latest swift and using a extension of the UIViewController class :

extension UIViewController {
    func embed(_ viewController:UIViewController, inView view:UIView){
        viewController.willMove(toParent: self)
        viewController.view.frame = view.bounds
        view.addSubview(viewController.view)
        self.addChild(viewController)
        viewController.didMove(toParent: self)
    }
}
Krunal Nagvadia
  • 1,083
  • 2
  • 12
  • 33
Vlad
  • 191
  • 1
  • 3
4

You can have a generic method like:

func embed(_ viewController:UIViewController, inParent controller:UIViewController, inView view:UIView){
   viewController.willMove(toParent: controller)
   viewController.view.frame = view.bounds
   view.addSubview(viewController.view)
   controller.addChild(viewController)
   viewController.didMove(toParent: controller)
}

Hope it helps

Pablo Blanco
  • 679
  • 8
  • 14