Search code examples
swiftxcodetvos

How to switch between storyboards without using tab bar controller


I have 3 Storyboards (Main, First, and Second), Storyboard Main contains two buttons inside its View on the top left corner (button: First, and button: second), without using Tab Bar controller how can I switch between First and Second from the Main storyboard while keeping the two buttons visible at all times? I’ve tried using Storyboard Reference but when selecting one of the buttons it just segues into the selected storyboard and that doesn’t work because Buttons need to be visible in the view container from Main storyboard, Container View seemed like an option but not sure how to switch between storyboards in that view container while keeping the buttons visible.

Please help. Thank you enter image description here


Solution

  • You don't have to use the Storyboard Reference in Interface Builder. You create the references programmatically, which I find simpler and easier to understand anyway.

    Interface Builder

    Make sure you set FirstViewController and SecondViewController as the initial controllers of their respective storyboards by checking "Is Initial View Controller".

    Interface Builder Setup

    Code

    class MainViewController: UIViewController {
        @IBOutlet weak var contentView: UIView!
    
        // Initialize the first view controller of storyboard
        let firstViewController: FirstViewController = {
            let storyboard = UIStoryboard(name: "First", bundle: nil)
            return storyboard.instantiateInitialViewController() as! FirstViewController
        }()
    
        // Initialize the second view controller of storyboard
        let secondViewController: SecondViewController = {
            let storyboard = UIStoryboard(name: "Second", bundle: nil)
            return storyboard.instantiateInitialViewController() as! SecondViewController
        }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            show(childViewController: firstViewController)
        }
    
        @IBAction func showFirstVC(_ sender: Any) {
            // Don't show the first view controller again if it's already visible
            guard firstViewController.parent != self else { return }
            removeAllChildViewControllers()
            show(childViewController: firstViewController)
        }
    
        @IBAction func showSecondVC(_ sender: Any) {
            // Don't show the second view controller again if it's already visible
            guard secondViewController.parent != self else { return }
            removeAllChildViewControllers()
            show(childViewController: secondViewController)
        }
    
        // MARK: - Helper methods
        // Show a view controller in the `contentView`
        func show(childViewController vc: UIViewController) {
            self.addChildViewController(vc)
            self.contentView.addSubview(vc.view)
            vc.didMove(toParentViewController: self)
        }
    
        // Remove a view controller from the `contentView`
        func remove(childViewController vc: UIViewController) {
            vc.willMove(toParentViewController: nil)
            vc.removeFromParentViewController()
            vc.view.removeFromSuperview()
        }
    
        // Remove all child view controllers
        func removeAllChildViewControllers() {
            for childVC in self.childViewControllers {
                remove(childViewController: childVC)
            }
        }
    }