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
It's Matthias Bauch solution, but thought of sharing it in Swift anyway!Edit:Adding a link to a Swift 2.0 ready made demo app.https://github.com/ahmed-abdurrahman/taby-segmented-control
var currentViewController: UIViewController?@IBOutlet weak var contentView: UIView!@IBOutlet weak var segmentedControl: UISegmentedControl!@IBAction func switchHappeningTabs(sender: UISegmentedControl) { if let vc = viewControllerForSelectedSegmentIndex(sender.selectedSegmentIndex) { self.addChildViewController(vc) self.transitionFromViewController(self.currentViewController!, toViewController: vc, duration: 0.5, options: UIViewAnimationOptions.TransitionFlipFromRight, animations: { self.currentViewController!.view.removeFromSuperview() vc.view.frame = self.contentView.bounds self.contentView.addSubview(vc.view) }, completion: { finished in vc.didMoveToParentViewController(self) self.currentViewController!.removeFromParentViewController() self.currentViewController = vc } ) }}override func viewDidLoad() { super.viewDidLoad() if let vc = self.viewControllerForSelectedSegmentIndex(self.segmentedControl.selectedSegmentIndex) { self.addChildViewController(vc) self.contentView.addSubview(vc.view) self.currentViewController = vc }}func viewControllerForSelectedSegmentIndex(index: Int) -> UIViewController? { var vc: UIViewController? switch index { case 0: vc = self.storyboard?.instantiateViewControllerWithIdentifier("FooViewController") as? UIViewController case 1: vc = self.storyboard?.instantiateViewControllerWithIdentifier("BarViewController") as? UIViewController default: return nil } return vc}
For someone want to implement the same in swift
import UIKitclass HomeController: UIViewController { var currentViewController:UIViewController? @IBOutlet weak var homeController: UIView! override func viewDidLoad() { super.viewDidLoad() let initialController:UIViewController = self.viewControllerForSegmentedIndex(0) self.addChildViewController(initialController) initialController.view.frame = self.homeController.bounds self.homeController.addSubview(initialController.view) self.currentViewController = initialController } @IBAction func segmentChanged(sender: UISegmentedControl) { let viewCOntroller:UIViewController = viewControllerForSegmentedIndex(sender.selectedSegmentIndex) self.addChildViewController(viewCOntroller) self.transitionFromViewController(self.currentViewController!, toViewController: viewCOntroller, duration: 0.5, options: UIViewAnimationOptions.TransitionFlipFromBottom, animations: { self.currentViewController?.view.removeFromSuperview() viewCOntroller.view.frame = self.homeController.bounds self.homeController.addSubview(viewCOntroller.view) }, completion:{ finished in viewCOntroller.didMoveToParentViewController(self) self.currentViewController?.removeFromParentViewController() self.currentViewController = viewCOntroller }) } func viewControllerForSegmentedIndex(index:Int) -> UIViewController { var viewController:UIViewController? switch index { case 0: viewController = self.storyboard?.instantiateViewControllerWithIdentifier("StoryboardIdForFirstController") break case 1: viewController = self.storyboard?.instantiateViewControllerWithIdentifier("StoryboardIdForSecondController") break case 2: viewController = self.storyboard?.instantiateViewControllerWithIdentifier("StoryboardIdForThirdController") break default: break } return viewController! }}
Storyboard view