kevindeleon
kevindeleon

Reputation: 1924

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.

Upvotes: 17

Views: 8246

Answers (4)

kevindeleon
kevindeleon

Reputation: 1924

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."

Upvotes: 17

rmp
rmp

Reputation: 3503

To answer your second question about it being "brittle"

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.

Upvotes: 1

Max
Max

Reputation: 5932

I have simulated the same, refer link :-https://github.com/deepesh259nitk/MultipleStoryBoards/tree/master

  1. Run the project
  2. Tap on Tab2
  3. you will see 3 buttons
  4. Tap on button3

Upvotes: 1

rmp
rmp

Reputation: 3503

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];
            }
        }

Upvotes: 2

Related Questions