iosswiftuitabbarcontrolleruimodalpresentationstyle

How to PopUp or Modally Present View Controller from Tab Bar Controller?


How can I create a popup that appears when a button on a Tab Bar is pressed? I would like something similar to this: https://www.youtube.com/watch?v=zDWSaItF2ko.

I have tried many solutions but none have worked.

For example, I have tried this with my main view controller:

This still doesn't work though. How would I go about creating this. I know that I need to present the view controller modally and over current context, but how would I do that from a tab bar controller.

func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
    if viewController is PopupViewController {
        if let popupView = tabBarController.storyboard?.instantiateInitialViewController() {
            popupView.modalPresentationStyle = .fullScreen
            tabBarController.present(popupView, animated: true, completion: nil)

            return false
        }
    }
    return true
}

Here are some pictures that may help:

Main Storyboard:

Main Storyboard

Popup Storyboard:

Popup Storyboard

View Controller Code:

View Controller Code


Solution

  • Have you tried debug this using breakpoints in Xcode? From what I can see, the first thing you do is to check whether the view controller that should be selected is of class PopupViewController. Are you sure the view controller is being instantiated correctly?

    And by the way I would recommend another way of instantiating the view controller from storyboard rather then:

    tabBarController.storyboard?.instantiateInitialViewController()
    

    The first thing is to head over to the storyboard file itself and in the view controller you are trying to instantiate change the Storyboard ID to something for example the class of the storyboard (PopupViewController in your case).

    Next you will want to try to instantiate the storyboard itself using the init(name: String, bundle storyboardBundleOrNil: Bundle?) initialiser:

    let storyboard = UIStoryboard(name: "Popup", bundle: nil)
    

    And now instantiate the view controller using the storyboard variable like so:

    let popupViewController  = storyboard.instantiateViewController(withIdentifier: "PopupViewController") as! PopupViewController
    

    Finally you can give it some extra configuration and present it on the tab bar controller:

    popupViewController.modalPresentationStyle = .fullScreen
    tabBarController.present(popupViewController, animated: true)
    

    Edit

    Addionally to make it more Swifty, I recommend guard statement for early exit. Finally the method could look something like this:

    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
        guard viewController is PopupViewController else { return true }
        let storyboard = UIStoryboard(name: "Popup", bundle: nil)
        let popupViewController = storyboard.instantiateViewController(withIdentifier: "PopupViewController") as! PopupViewController
        popupViewController.modalPresentationStyle = .fullScreen
        tabBarController.present(popupViewController, animated: true, completion: nil)
        return false
    }