Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to open a modal with UITabBarController and on close, display last tab bar view?

So I have a UITabBarController on one storyboard that has 3 buttons. Two of them open standard views associated with the tab bar by standard view association segues... the third item is the issue.

I would like to open a form that lives in another storyboard (shared by other views in the app) in a modal view, and upon close or submit, just return to whatever tab was previously active in the tabbed view.

I've seen a few "options" out there, but none of them seem like exactly what I am looking to do.

Any ideas?

EDIT: It got edited out of my original question by a mod, but I am writing this in Swift...not Obj-C.

like image 538
kevindeleon Avatar asked Jun 25 '15 14:06

kevindeleon


People also ask

How do you hide the tab bar when a view controller is shown?

If you don't want that behavior, you should set hidesBottomBarWhenPushed to true where applicable. This will hide the tab bar along with any toolbars you had showing, but only when a view controller is pushed onto the navigation stack. This allows you to show the tab bar at first, then hide it when you need more room.

How do I add a tab bar to an existing view controller storyboard?

To add a tab, first drag a new View Controller object to the storybard. Next control-drag from the tab bar controller to new view controller and select view controllers under Relationship Segue . Your tab bar controller will update with a new tab.

What is tab view in Swift?

A view that switches between multiple child views using interactive user interface elements.


2 Answers

So I have a potential solution that works using a blank view controller, shouldSelectViewController and the UITabBarController Delegate. The only issue is, I'm not particularly happy with how brittle it is.

func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) -> Bool {

    // This is a bit dangerous if we move where 'newController' is located in the tabs, this will break.
    let newController = viewControllers![1] as! UIViewController

    // Check if the view about to load is the second tab and if it is, load the modal form instead.
    if viewController == newController {
        let storyboard = UIStoryboard(name: "ModalController", bundle: nil)
        let vc = storyboard.instantiateInitialViewController() as? UIViewController

        presentViewController(vc!, animated: true, completion: nil)

        return false
    } else {
        return true
    }
}

This works fine, but if someone were to come along and re-arrange the order of the tabs in the storyboard, this would break.

Also to give @rmp some credit, another options is "If you provide a title for all of your root viewControllers that make up the tabs in your tabBarController than you you can use viewController.title to check which tab was tapped in the shouldSelectViewController delegate. Of course you still run the risk of someone renaming your views title property."

like image 106
kevindeleon Avatar answered Nov 14 '22 09:11

kevindeleon


It sounds like you don't really want a tab, tabs are meant to contain a view and not present a new/modal view. However, there are cases where what you want to do make sense, like some apps will use the center tab as a button to add a new item or perform some actions (Yelp is a good example). In these cases, the tab is usually larger or visually different to signify that it is not really a tab. This is what I think you are really after.

To do this you need to:

  1. Create a tab in the tabBar this will just be a place holder
  2. Create an icon or image to be used as a button that will go over the placeholder tab
  3. Use the viewWillLayoutSubviews of your tabBarController class to place the button over the placeholder tab. See below (portrait example code).
  4. Add an action to the button that will present your modal view.

Note: you may need to adjust the placement of the button using the code below to match your needs.

-(void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];

            if (UIDeviceOrientationIsPortrait && !centerTabButton) {

                //CUSTOM CENTER TAB BAR BUTTON
                UIImage *buttonImage = [UIImage imageNamed:@"icn_CenterTabBarIcon.png"];
                UIImage *highlightImage = [UIImage imageNamed:@"icn_CenterTabBarIcon.png"];

                centerTabButton = [UIButton buttonWithType:UIButtonTypeCustom];
                centerTabButton.frame = CGRectMake(0.0, 0.0, buttonImage.size.width, buttonImage.size.height);
                [centerTabButton setBackgroundImage:buttonImage forState:UIControlStateNormal];
                [centerTabButton setBackgroundImage:highlightImage forState:UIControlStateHighlighted];
                [centerTabButton setShowsTouchWhenHighlighted:FALSE];
                [centerTabButton setAdjustsImageWhenHighlighted:FALSE];
                [centerTabButton addTarget:self action:@selector(centerTabClicked:) forControlEvents:UIControlEventTouchUpInside];

                CGFloat heightDifference = buttonImage.size.height - self.tabBar.frame.size.height;

                //center the button on the tab bar based on the tab bar's height
                if (heightDifference < 0){
                    centerTabButton.center = self.tabBar.center;
                }
                else{
                    CGPoint center = self.tabBar.center;
                    center.y = center.y - heightDifference/2.0;
                    centerTabButton.center = center;
                }

                [self.view addSubview:centerTabButton];
            }
        }
like image 36
rmp Avatar answered Nov 14 '22 08:11

rmp