Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Presenting a modal from a UITabBarController

Similar to Instagram and other popular apps, I'd like one of the buttons in my UITabBarController to present its view controller as a full-screen modal instead of a normal tab. I've used Storyboards to connect the UITabBarController to all of its child view controllers and I can't figure out how to present the one view controller as a modal. I found some other questions on here asking about the same thing but they seem to be assembling the tab bar manually instead of using segues like I did. Is this even possible the way I'm doing it?

like image 871
bloudermilk Avatar asked Aug 02 '14 22:08

bloudermilk


People also ask

What is a modal presentation?

Modality is a design technique that presents content in a separate, focused mode that prevents interaction with the parent view and requires an explicit action to dismiss. Presenting content modally can: Ensure that people receive critical information and, if necessary, act on it.

What is tab bar controller in Swift?

What's A Tab Bar Controller? A tab bar controller, of class UITabBarController, is a container view controller. It typically organizes 3-5 view controllers in a group. The user of your app can switch between view controllers by tapping one of the tabs in the tab bar at the bottom of the screen.


1 Answers

tldr - Check out the code below.

I started with axxixc's approach but ran into some issues. I was attempting to show the view modally by implementing tabBarController:shouldSelectViewController: of UITabBarControllerDelegate. However, iOS was complaining about the view already being in the view hierarchy, which is obvious once you think about it because the whole point of using the UITabBarController in IB is so that iOS handles instantiating these views for us. So next I removed the view from it's parent and that stopped the errors but the approach still felt wrong and brittle. It also didn't give me any control over whether I wanted to re-instantiate the view each time the model popped up, which in my case I did.

So what I ended up doing is, in IB, connecting that specific tab to an empty view controller that would effectively act as a placeholder. I override the same tabBarController:shouldSelectViewController: method and check for the title of the view controller. If it matches the dummy title that I set in IB, I stop the tab bar controller from showing the dummy controller by returning false after showing my own view modally.

Here's the code:

func tabBarController(tabBarController: UITabBarController!, shouldSelectViewController viewController: UIViewController!) -> Bool {
    if viewController.title? == DUMMY_POST_VIEW_CONTROLLER_TITLE {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let actualController = storyboard.instantiateViewControllerWithIdentifier("ActualViewController") as ActualViewController
        presentViewController(actualController, animated: true, completion: nil)
        return false
    }

    return true
}
like image 105
bloudermilk Avatar answered Oct 17 '22 09:10

bloudermilk