0

I have a view controller that contains a collectionView with 2 sections. The header of the second section is a sticky header and it has a segmentedControl inside of it:

ParentViewController
    --collectionView
         --sectionOne // because there is specific data in sectionOne I cannot use a PageViewController
         --sectionTwo
           sectionTwoHeader // sticky header
           [RedVC, BlueVC, GreenVC] // these should be the size of sectionTwo

When a segment is selected I'm using a ContainerVC that will show a view controller corresponding to each segment:

// each of of these color vcs have collectionViews inside of them
RedCollectionViewController(), BlueCollectionViewController(), GreenCollectionViewController()

The problem is when the segment is selected the collectionView isn't showing any of the color view controllers it's supposed to show. How do I add each color vc using addChildViewController() to a collectionView?

The collectionView w/ segmentedControl's selectedIndex:

class ParentViewController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout{

    var collectionView: UICollectionView!
    var containerController: ContainerController!
    var vc: UIViewController!

    override func viewDidLoad() {
        super.viewDidLoad()
        containerController = ContainerController()
    }

    @objc func selectedIndex(_ sender: UISegmentedControl){

        let index = sender.selectedSegmentIndex

        switch index {
        case 0:
            containerController.vcIdentifierReceivedFromParent(segment: "BlueVC")
            break
        case 1:
            containerController.vcIdentifierReceivedFromParent(segment: "RedVC")
            break
        case 2:
            containerController.vcIdentifierReceivedFromParent(segment: "GreenVC")
            break
        default: break
       }

        /*
        // because of the X and Y values this adds the containerVC over the collectionView instead of under the sectionTwo segmented Control header 
        vc = containerController
        addChildViewController(vc)
        vc.view.frame = CGRect(x: 0,y: 0, width: collectionView.frame.width,height: collectionView.frame.height)
        view.addSubview(vc.view)
        vc.didMove(toParentViewController: self)
        lastViewController = vc
        */
    }
}

ContainerVC:

class ContainerController: UIViewController {

var vc: UIViewController!
var lastViewController: UIViewController!

override func viewDidLoad() {
    super.viewDidLoad()

    view.backgroundColor = .white
    vcIdentifierReceivedFromParent(segment: "RedVC")
}

func vcIdentifierReceivedFromParent(segment: String){

    switch segment {

    case "RedVC":

        let redVC = RedCollectionViewController()
        addVcToContainer(destination: redVC)
        break

    case "BlueVC":

        let blueVC = BlueCollectionViewController()
        addVcToContainer(destination: blueVC)
        break

    case "GreenVC":

        let greenVC = GreenCollectionViewController()
        addVcToContainer(destination: greenVC)
        break

    default: break
    }
}

func addVcToContainer(destination: UIViewController) {

        //Avoids creation of a stack of view controllers
        if lastViewController != nil{
            lastViewController.view.removeFromSuperview()
        }

        self.vc = destination
        addChildViewController(vc)
        vc.view.frame = CGRect(x: 0,y: 0, width: view.frame.width,height: view.frame.height)
        view.addSubview(vc.view)
        vc.didMove(toParentViewController: self)
        lastViewController = vc
    }
}
Lance Samaria
  • 17,576
  • 18
  • 108
  • 256
  • Why collectionVC? Why not UIPageViewController? – Sandeep Bhandari Jun 19 '18 at 06:36
  • hey thanks for the help. I figured since I had the segmented control and each segment is showing a different collection view that the segmented control was best to use. Is there anything wrong with using it? – Lance Samaria Jun 19 '18 at 06:38
  • You have `let containerController = ContainerController()` and `var containerController: ContainerController!` in a subsequent statements! And `var containerController` is not initialized in `ViewDidLoad` – Sandeep Bhandari Jun 19 '18 at 06:38
  • that was a typo. I'll fix it. I didn't add viewDidLoad because it really didn't make a difference to put the code there because regardless it get's initialized there – Lance Samaria Jun 19 '18 at 06:40
  • If your collectionView is not adding any benefit then using `PageViewController` makes sense. PageViewController directly loads ViewControllers rather than u creating collectionView and adding them as childVC to collectionView – Sandeep Bhandari Jun 19 '18 at 06:40
  • Actually I cannot use a PageViewController. I forgot the collectionView has 2 sections. The first section is a cell that shows specific information. I didn't add it because that section doesn't;t make a difference in the code. Because of this I have to use a collectionVIew – Lance Samaria Jun 19 '18 at 06:44
  • Usually u use a ViewController drag SegmentController and drag a container view and attach it to PageViewController and add VCs to PageViewController. Follow any tutorial on PageVC should help u. Add a IBAction to segment controller and in IBAction simply change the selected viewController index in pageViewController n ull be sorted :) – Sandeep Bhandari Jun 19 '18 at 06:45
  • Have you specified height for section header where your collection view is supposed to appear. Do u see that section? – Sandeep Bhandari Jun 19 '18 at 06:46
  • 1
    Thanks, this projects 100% programmatic. Read my comment above. I actually have to use a collection view because of the first section – Lance Samaria Jun 19 '18 at 06:46
  • I'm using a StickyHeader. Look here: func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize { // Section 0 has no Header if section == 0{ return CGSize.zero } // Section 1 Header for SegmentedControl return CGSize(width: view.frame.size.width, height: 37) } – Lance Samaria Jun 19 '18 at 06:48

1 Answers1

0

You are adding Red / Blue / Green VCs to Container View controller that is referenced from inside ParentViewController. But you are adding each of them inside ContainerVC topmost view, whose frame is probably never set, as far as I can see from your code.

It's probably CGRectZero.

Adding child VC views to this view will result in they are getting wrongly positioned, or not positioned at all. Because Container View controller is nowhere in the view controller hierarchy. You are effectively doing everything within ParentViewController's viewDidLoad(). Most probably, ContainerVC's viewDidLoad is not even called. Hence its view is never initialised properly.

You probably do not need ContainerVC at all. Try adding children to ParentViewController, and try adding them after viewDidLoad() call, i.e. in viewDidAppear(), viewDidLayoutSubviews() and upon switch segment selection.

Nirav Bhatt
  • 6,940
  • 5
  • 45
  • 89