Kobe Kobe - 2 months ago 27
Swift Question

How to load a UIViewController inside an UIScrollView

This is my setup. I have an

UIScrollView
on top of my main view controller in which I load multiple view controllers. I also have an Add button which will present a new view controller using a Push segue.

I want this view controller to also load only on top of the scroll view and not the all screen.

I tried 2 different things until now, but none of the work:


  1. Add view controller inside scroll view in
    prepareForSegue
    :

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let addViewController = segue.destination as! AddViewController

    addChildViewController(addViewController)
    addViewController.view.frame = CGRect(x: 0, y: 0, width: width, height: height)
    scrollView.addSubview(addViewController.view)
    didMove(toParentViewController: self)
    }

  2. Add view controller in UIButton action:



@IBAction func addDidTouch(_ sender: AnyObject) {

let addViewController = AddViewController()

addChildViewController(addViewController)
addViewController.view.frame = CGRect(x: 0, y: 0, width: width, height: height)
scrollView.addSubview(addViewController.view)
didMove(toParentViewController: self)
}


Both of this solutions crashes my app.

Is there a way to implement this correctly ?

Answer

You cannot push any view controller on the same view controller, you need to add container view to your scroll view. And then if you want you may scroll the scroll on tap of the add button, so that it will seem like new controller is being added to it. It can be done like this,

scrollView.contentSize = CGSize(width: screenWidth*3, height: 1)

    let first = getStoryboard(StoryboardName.Main).instantiateViewControllerWithIdentifier("FirstViewController") as! FirstViewController

    let second = getStoryboard(StoryboardName.Main).instantiateViewControllerWithIdentifier("SecondViewController") as! SecondViewController

    let third = getStoryboard(StoryboardName.Main).instantiateViewControllerWithIdentifier("ThirdViewController") as! ThirdViewController

    self.addChildViewController(first)
    self.scrollView.addSubview(first.view)
    first.willMoveToParentViewController(self)

    self.addChildViewController(second)
    self.scrollView.addSubview(second.view)
    second.willMoveToParentViewController(self)

    self.addChildViewController(third)
    self.scrollView.addSubview(third.view)
    third.willMoveToParentViewController(self)

    first.view.frame.origin = CGPointZero
    second.view.frame.origin = CGPoint(x: screenWidth, y: 0)
    third.view.frame.origin = CGPoint(x: 2*screenWidth, y: 0)

You may want to disable scroll of your scroll view if you want just to add(move) to another view controller only by your add button.