Swift - How to Link Two View Controllers into One Container View and Switch Between Them Using Segmented Control

Switch the sub viewController use segmented control

Follow below steps.

  1. Add VC1 & VC2 as a childVC of mainVC.

  2. On segment 1 selection VC1.view.hidden = false & vc2.view.hidden = true

  3. On segment 2 selection VC2.view.hidden = false & vc1.view.hidden = true

take reference

  1. How-to-add-childVC

  2. How-tobind-segment-control-action

Code work

@IBAction func indexChanged(_ sender: AnyObject) {
switch segmentedControl.selectedSegmentIndex
{
case 0:
vc1.view.hidden = false
vc2.view.hidden = true
case 1:
vc2.view.hidden = false
vc1.view.hidden = true
default:
break
}
}

Change views using Segmented Control

Here i have created a complete solution as per your requirement.

Swift 4

//
// SegementedVC.swift
//
// Created by Test User on 01/02/18.
// Copyright © 2018 Test User. All rights reserved.
//

import UIKit

class SegementedVC: UIViewController {

//----------------------------------------------------------------
// MARK:-
// MARK:- Outlets
//----------------------------------------------------------------

@IBOutlet weak var segmentControl : UISegmentedControl!
@IBOutlet weak var containerView : UIView!

//----------------------------------------------------------------
// MARK:-
// MARK:- Variables
//----------------------------------------------------------------

private lazy var firstViewController: FirstViewController = {
// Load Storyboard
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)

// Instantiate View Controller
var viewController = storyboard.instantiateViewController(withIdentifier: "FirstViewController") as! FirstViewController

// Add View Controller as Child View Controller
self.add(asChildViewController: viewController)

return viewController
}()

private lazy var secondViewController: SecondViewController = {
// Load Storyboard
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)

// Instantiate View Controller
var viewController = storyboard.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController

// Add View Controller as Child View Controller
self.add(asChildViewController: viewController)

return viewController
}()

//----------------------------------------------------------------
// MARK:-
// MARK:- Abstract Method
//----------------------------------------------------------------

static func viewController() -> SegementedVC {
return UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SegementedView") as! SegementedVC
}

//----------------------------------------------------------------
// MARK:-
// MARK:- Memory Management Methods
//----------------------------------------------------------------

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}

//----------------------------------------------------------------
// MARK:-
// MARK:- Action Methods
//----------------------------------------------------------------

@IBAction func segmentValueChanged(_ sender: UISegmentedControl) {
updateView()
}

//----------------------------------------------------------------
// MARK:-
// MARK:- Custom Methods
//----------------------------------------------------------------

private func add(asChildViewController viewController: UIViewController) {

// Add Child View Controller
addChildViewController(viewController)

// Add Child View as Subview
containerView.addSubview(viewController.view)

// Configure Child View
viewController.view.frame = containerView.bounds
viewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]

// Notify Child View Controller
viewController.didMove(toParentViewController: self)
}

//----------------------------------------------------------------

private func remove(asChildViewController viewController: UIViewController) {
// Notify Child View Controller
viewController.willMove(toParentViewController: nil)

// Remove Child View From Superview
viewController.view.removeFromSuperview()

// Notify Child View Controller
viewController.removeFromParentViewController()
}

//----------------------------------------------------------------

private func updateView() {
if segmentControl.selectedSegmentIndex == 0 {
remove(asChildViewController: secondViewController)
add(asChildViewController: firstViewController)
} else {
remove(asChildViewController: firstViewController)
add(asChildViewController: secondViewController)
}
}

//----------------------------------------------------------------

func setupView() {
updateView()
}

//----------------------------------------------------------------
// MARK:-
// MARK:- View Life Cycle Methods
//----------------------------------------------------------------

override func viewDidLoad() {
super.viewDidLoad()
self.setupView()
}

//----------------------------------------------------------------

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}

//----------------------------------------------------------------

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
}

Storyboard Screenshots

Sample Image

Sample Image

Sample Image

Swift - Segmented control - Switch multiple views

You can use the isHidden property of the UIView to show/hide your required views.
First you have to link both views to IBOutlets through the Interface builder

@IBOutlet weak var historyView: UIView!
@IBOutlet weak var popularView: UIView!

@IBAction func indexChanged(_ sender: UISegmentedControl) {
switch segmentedControl.selectedSegmentIndex {
case 0:
historyView.isHidden = true
popularView.isHidden = false
case 1:
historyView.isHidden = false
popularView.isHidden = true
default:
break;
}
}

Note: it was named hidden in Swift 1 and 2.

Swift how to use container view and segmented control

You got very common mistake and error. But don't worry.

Check your full error message. There must be a clue what variable you are trying to access and getting nil (it might be resultLabel).

Then make sure the connection between storyboard and view controller for this variable is correct. You can try to remove and create it again if you don't get what is wrong.

If you need more help, please show us full error message.

How can I use segmented control from container view to control my main view

I've found solution for this.

class FirstTestTableViewController: UITableViewController, ScrollSegmentDelegate {

func segmentIsChosen(segment: Int) {
print(segment)
questionNumber = segment + 1
}

var questionNumber = 0

func updateQuestionNumber() {
questionNumber + 1
scrollSegmentVC?.questionNumberToReceive = questionNumber
}

var scrollSegmentVC: ScrollSegmentVC?

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segment" {
scrollSegmentVC = segue.destination as? ScrollSegmentVC
scrollSegmentVC?.delegate = self
}
}

iOS Swift Segmented control with container view for switching - views are not loading first time

You can try added this code after method viewDidLoad, for show animation after app loaded.

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

UIView.animateWithDuration(0.5, animations: {
self.containerViewA.alpha = 1
self.containerViewB.alpha = 0
}
}

Switching ViewControllers with UISegmentedControl in iOS5

This code works pretty well for your purpose, I use it for one of my new apps.

It uses the new UIViewController containment APIs that allow UIViewControllers inside your own UIViewControllers without the hassles of manually forwarding stuff like viewDidAppear:

- (void)viewDidLoad {
[super viewDidLoad];
// add viewController so you can switch them later.
UIViewController *vc = [self viewControllerForSegmentIndex:self.typeSegmentedControl.selectedSegmentIndex];
[self addChildViewController:vc];
vc.view.frame = self.contentView.bounds;
[self.contentView addSubview:vc.view];
self.currentViewController = vc;
}
- (IBAction)segmentChanged:(UISegmentedControl *)sender {
UIViewController *vc = [self viewControllerForSegmentIndex:sender.selectedSegmentIndex];
[self addChildViewController:vc];
[self transitionFromViewController:self.currentViewController toViewController:vc duration:0.5 options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{
[self.currentViewController.view removeFromSuperview];
vc.view.frame = self.contentView.bounds;
[self.contentView addSubview:vc.view];
} completion:^(BOOL finished) {
[vc didMoveToParentViewController:self];
[self.currentViewController removeFromParentViewController];
self.currentViewController = vc;
}];
self.navigationItem.title = vc.title;
}

- (UIViewController *)viewControllerForSegmentIndex:(NSInteger)index {
UIViewController *vc;
switch (index) {
case 0:
vc = [self.storyboard instantiateViewControllerWithIdentifier:@"FooViewController"];
break;
case 1:
vc = [self.storyboard instantiateViewControllerWithIdentifier:@"BarViewController"];
break;
}
return vc;
}

I got this stuff from chapter 22 of Ray Wenderlichs book iOS5 by tutorial.
Unfortunately I don't have a public link to a tutorial. But there is a WWDC 2011 video titled "Implementing UIViewController Containment"

EDIT

self.typeSegmentedControl is outlet for your UISegmentedControl

self.contentView is outlet for your container view

self.currentViewController is just a property that we're using to store our currently used UIViewController



Related Topics



Leave a reply



Submit