Skip to content

Instantly share code, notes, and snippets.

@nguyentruongky
Last active April 13, 2017 03:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nguyentruongky/725c475650e8ade4126f93da27d16579 to your computer and use it in GitHub Desktop.
Save nguyentruongky/725c475650e8ade4126f93da27d16579 to your computer and use it in GitHub Desktop.
A sample to load controller dynamically into view

Load dynamic view controller into other one

I saw a question on stackoverflow. He ran into a problem when use ContainerView to embed other view controller. I'll share what I did.

  • Create new project.
  • Design what you want. I add a label, a segmented control and a container view to embed child controller.

  • Select all controls and choose menu Editor\Embed In\View. Name it: Content View.

  • Select Content View and embed into ScrollView.

  • Set constraint for ScrollView: leading, trailing, top, bottom to super view equal 0.

  • Set constraint for Content View: leading, trailing, top, bottom to ScrollView equal to 0, vertical and horizontal alignment.

  • Connect outlets and action to your controller.

  • Add your new controllers. In my demo, I added 2 TableViewController, 1 for displaying images (ImageController), 1 for loading text (TextController).

  • Back to your main view controller, add some code.

      var dynamicHeight: CGFloat = 0
      
      @IBOutlet weak var scrollView: UIScrollView!
    
      @IBOutlet weak var pageContainer: UIView!
      
      @IBAction func selectPage(sender: AnyObject) {
      
      	// remove child controllers before add others
          for controller in childViewControllers {
              
              controller.removeFromParentViewController()
          }
          
          for view in pageContainer.subviews {
              
              view.removeFromSuperview()
          }
          
          let segment = sender as! UISegmentedControl
          
          if segment.selectedSegmentIndex == 0 {
              
              createImageController()
          }
          else {
              
              createTextController()
          }
          
          updateScrollContentSize()
      }
      
      func updateScrollContentSize() {
          
          // 150 is your other view height. 
          scrollView.contentSize = CGSize(width: view.frame.size.width, height: dynamicHeight + 150)
      }
      
      func createTextController() {
          
          let textController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("TextController") as! TextController
          dynamicHeight = textController.getTableContentHeight()
          textController.tableView.scrollEnabled = false
          
          self.addChildViewController(textController)
          pageContainer.addSubview(textController.view)
          textController.view.frame = CGRectMake(0, 0, pageContainer.frame.size.width, dynamicHeight)
      }
      
      func createImageController() {
          
          let imageController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("ImageShowController") as! ImageShowController
          dynamicHeight = imageController.getTableContentHeight()
          imageController.tableView.scrollEnabled = false
          
          self.addChildViewController(imageController)
          pageContainer.addSubview(imageController.view)
          imageController.view.frame = CGRectMake(0, 0, pageContainer.frame.size.width, dynamicHeight * 2)
      }
    
      override func viewDidAppear(animated: Bool) {
          
          super.viewDidAppear(true)
          createImageController()
          updateScrollContentSize()
      }
    
  • Xcode tells you about the error. Fix it now. Open your controller you want to embed and add some code.

      func getTableContentHeight() -> CGFloat {
          
          // calculate the total height of your controller. 
          return CGFloat(vietnamTravelLocations.count) * 44
      }
    

It's done, run your project and see the result.

Conclusion

Container view is very convenient, But don't exploit it, especially when your embed controller change the height many times. Your app will be lag, unstable and bring a bad experience to your user.

You can download my demo at my github

Hope this can help.

Written on Jan 29, 2016.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment