0

In my main view Controller, I have a segmented control and a container view below. I want to change the container view whenever I switch the segmented control. When I switch over the tab, I can see the very view being loaded (print in viewDidload), however, I find it not working with the datasource of collectionViewDataSource. Any ideas?

enter image description here

// Main View
let videoViewController = VideoViewController()
let photoViewController = PhotoViewController()


private var activeViewController: UIViewController? {
    didSet {
        removeInactiveViewController(oldValue)
        updateActiveViewController()
    }
}

@IBOutlet weak var containerView: UIView!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    activeViewController = videoViewController

}

@IBAction func segmentDidChanged(sender: UISegmentedControl) {
    if sender.selectedSegmentIndex == 0 {
        print("\(sender.titleForSegmentAtIndex(0)!) Selected")
        activeViewController = videoViewController

    } else if sender.selectedSegmentIndex == 1 {
        print("\(sender.titleForSegmentAtIndex(1)!) Selected")
        activeViewController = photoViewController
    }
}


private func removeInactiveViewController(inactiveViewController: UIViewController?) {
    if let inActiveVC = inactiveViewController {
        // call before removing child view controller's view from hierarchy
        inActiveVC.willMoveToParentViewController(nil)

        inActiveVC.view.removeFromSuperview()

        // call after removing child view controller's view from hierarchy
        inActiveVC.removeFromParentViewController()
    }
}

private func updateActiveViewController() {
    if let activeVC = activeViewController {
        // call before adding child view controller's view as subview
        addChildViewController(activeVC)

        activeVC.view.frame = containerView.bounds
        containerView.addSubview(activeVC.view)

        // call before adding child view controller's view as subview
        activeVC.didMoveToParentViewController(self)
    }
}

// PhotoView
@IBOutlet weak var collectionView: UICollectionView!


override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
    print("HI")
}
extension PhotoViewController : UICollectionViewDataSource {

func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
    return 2
}

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 2
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as!PhotoCollectionViewCell
    cell.backgroundColor = UIColor.blackColor()
    // Configure the cell
    cell.imgView.image = UIImage(named: "test")
    return cell
}
}

When I make the PhotoViewController as initial controller, it works.

enter image description here

Willjay
  • 6,381
  • 4
  • 33
  • 58

1 Answers1

0

I have used the UIContainerView and UISegmentControl, if you use ContainerView show single UIViewController are already posted and the link are given below,

When I add a UIContainerView to a view controller it's type is UIView. How do I get to the viewcontroller for the embedded view?

or If you use ContainerView show two UIViewController when alernatively click UISegmentControl, to show single viewcontroller code is given below,

First create main ViewController, with create segmentController and containerView, then create Two ViewController name 'FirstViewController' and 'SecondViewController', then you put CollectionView from Any ViewController.

If you create the storyboard, then go MainViewController Class and create the outlet are

@property (weak, nonatomic) IBOutlet UIView *containerView;
@property (weak, nonatomic) IBOutlet UISegmentedControl *segmentControl;
@property (weak, nonatomic) UIViewController *currentViewController;

ViewDidLoad method:

UIFont *font = [UIFont boldSystemFontOfSize:16.0f];
    NSDictionary *attributes = [NSDictionary dictionaryWithObject:font
                                                           forKey:UITextAttributeFont];
    [segmentControl setTitleTextAttributes:attributes
                                    forState:UIControlStateNormal];

    _currentViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"FirstViewController"];
    _currentViewController.view.layer.cornerRadius = 8.0f;
    _currentViewController.view.translatesAutoresizingMaskIntoConstraints = NO;

    [self addChildViewController:_currentViewController];
    [self addSubview:_currentViewController.view toView:_containerView];

And UISegmentController method is given below,

-(IBAction)indexChanged:(UISegmentedControl *)sender
{
    if (sender.selectedSegmentIndex == 0) {
        UIViewController *newViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"FirstViewController"];
        newViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
        [self cycleFromViewController:self.currentViewController toViewController:newViewController];
        self.currentViewController = newViewController;
    }
    else if (sender.selectedSegmentIndex == 1)
    {
        UIViewController *newViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
        newViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
        [self cycleFromViewController:self.currentViewController toViewController:newViewController];
        self.currentViewController = newViewController;
    }
}

And the two view related Methods are,

- (void)addSubview:(UIView *)subView toView:(UIView*)parentView {
    [parentView addSubview:subView];

    NSDictionary * views = @{@"subView" : subView,};
    NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[subView]|"
                                                                   options:0
                                                                   metrics:0
                                                                     views:views];
    [parentView addConstraints:constraints];
    constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[subView]|"
                                                          options:0
                                                          metrics:0
                                                            views:views];
    [parentView addConstraints:constraints];
}

- (void)cycleFromViewController:(UIViewController*) oldViewController
               toViewController:(UIViewController*) newViewController {
    [oldViewController willMoveToParentViewController:nil];
    [self addChildViewController:newViewController];
    [self addSubview:newViewController.view toView:self.containerView];
    [newViewController.view layoutIfNeeded];

    // set starting state of the transition
    newViewController.view.alpha = 0;

    [UIView animateWithDuration:0.5
                     animations:^{
                         newViewController.view.alpha = 1;
                         oldViewController.view.alpha = 0;
                     }
                     completion:^(BOOL finished) {
                         [oldViewController.view removeFromSuperview];
                         [oldViewController removeFromParentViewController];
                         [newViewController didMoveToParentViewController:self];
                     }];
}

if you use these code alternativelly open the ViewController from UIContainerView when click SegmentControl, if work CollectionView from FirstViewController and its working for me!

Hope its helpful..

Community
  • 1
  • 1
Iyyappan Ravi
  • 3,205
  • 2
  • 16
  • 30
  • I'm able to switch over two views in the container with segmented controller, however, I got an error message if the view I added is collectionviewController. – Willjay Apr 12 '16 at 02:19
  • Error Msg occurs in addsubView: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'UICollectionView must be initialized with a non-nil layout parameter' – Willjay Apr 12 '16 at 02:20
  • if switch over two views in container with segmented control while using uitableview its working fine for me, i think you collectionview some error, its layout problem and i have solution given below [link](http://stackoverflow.com/questions/24288927/uicollectionview-must-be-initialized-with-a-non-nil-layout-parameter) – Iyyappan Ravi Apr 12 '16 at 04:25