0

I have created a UIViewController with a UITabbar in it.

enter image description here

I did not use UITabbarController because I wanted UITabbar on the top of the screen.

Upon clicking tab1, I want to present controller1 and on clicking tab2 I want to present controller 2. I don't want the tabbar to hide. I want to display the controller beneath the tabbar.

@interface MTLeaderFactoViewController () <UITabBarDelegate>
@property (weak, nonatomic) IBOutlet UITabBar *tabBar;
@end

@implementation MTLeaderFactoViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
}

- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
    if (item.tag == 0) {
        NSLog(@"item tag 0");
    } else {
        NSLog(@"item tag 1");
    }
}
@end

My questions:

1) didSelectItem method is not triggered even after using UITabbarDelegate

2) What is the most elegant way of displaying the controller when clicked on a button? I don't want to use segue as all the controllers are in different storyboards. For now, I plan to do

Controller1 *fp = [Controller1 controllerStoryboard:STORYBOARD_COURSE];
[self addChildViewController:fp];
[self.view addSubview:fp.view];
[fp didMoveToParentViewController:self];

EDIT 1:

    Controller1 *fp = [Controller1 controllerStoryboard:STORYBOARD_COURSE];
    [self addChildViewController:fp];
    [self.view addSubview:fp.view];
    [fp didMoveToParentViewController:self];

Tried this but it hides the tab bar. I want to utilize the space beneath the tab bar to display the controller

A_G
  • 2,260
  • 3
  • 23
  • 56

2 Answers2

2

What you need to do is have a basecontroller class which will contain a tabbar(programatically created) then you can achive the desired output heres a sample baseController that i created,

import UIKit

class BaseViewController: UIViewController,UITabBarDelegate{

    override func viewDidLoad() {
        super.viewDidLoad()

        let myTabBar = UITabBar()
        myTabBar.frame = CGRect(x: 0, y: 60, width:self.view.frame.size.width, height: 50)

        let one = UITabBarItem()
        one.title = "one"
        one.tag = 1
        let two = UITabBarItem()
        two.title = "two"
        two.tag = 2
        myTabBar.setItems([one,two], animated: false)
        self.view.addSubview(myTabBar)
        myTabBar.delegate = self

    }


    func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
        switch item.tag  {
        case 1:
            let controller = storyboard?.instantiateViewController(withIdentifier: "SecondViewController")
            addChildViewController(controller!)
            view.addSubview((controller?.view)!)
            controller?.didMove(toParentViewController: self)
            break
        case 2:
            let controller = storyboard?.instantiateViewController(withIdentifier: "ViewController")
            addChildViewController(controller!)
            view.addSubview((controller?.view)!)
            controller?.didMove(toParentViewController: self)
            break
        default:
            break
        }

    }

}

View Controller class :

import UIKit

class ViewController: BaseViewController {


    override func viewDidLoad() {
        super.viewDidLoad()
                // Do any additional setup after loading the view, typically from a nib.
    }


}

SecondView Controller :

import UIKit

class SecondViewController: BaseViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }



}
harshal jadhav
  • 5,456
  • 2
  • 18
  • 26
1

I would suggest using UITabBarController instead of UIViewController.

Add UITabViewController in your StoryBoard name it FirstTabBarController.

Add child view controller to FirstTabBarController. In all your child view of add UITabbar. Connect the TabBar delegate to each of your child ViewController.

Hide the default TabBar in your default FirstTabBarController.

- (void)viewWillAppear:(BOOL)animated {
     [super viewWillAppear:animated];
     self.tabBar.isHidden = true;
     [self setSelectedIndex:1];
  }

Add action to TabBar in your child ViewController as

- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
   NSUInteger index = [[theTabBar items] indexOfObject:item];
   NSLog(@"Tab index = %u", (int)indexO);
   [self.navigationController.tabBarController setSelectedIndex:index];
}

I would prefer this method over manually adding adding or removing ViewController as subview, let the UITabBarController manage that for you. Do let me know if you have further queries.

luckyShubhra
  • 2,731
  • 1
  • 12
  • 19
  • Hey - that should be okay. I am familiar with swift as well :) I didn't use UITabbarController because tabbar comes at the bottom by default and I didn't want to add hacks to move it to the top. – A_G Jul 26 '17 at 08:39
  • If I use the approach of using UITabbar, do you think it can cause issues? – A_G Jul 26 '17 at 08:43
  • Thats not hack. Its just a way to accomplish the task using default controller. child Viewcontroller is managed by TabBarController itself. You need not to manage it yourself in every view controller. Reduces coding to much extent. – luckyShubhra Jul 26 '17 at 08:45
  • 1
    No it wont cause any issue. You can do it according to your need and usage. – luckyShubhra Jul 26 '17 at 08:50
  • Thanks for the reply. I need to add one more button over the tabbar which should be accessible through all the screens. I believe going forward with the first approach would be easier for me. – A_G Jul 26 '17 at 08:50
  • Good Luck!! There are many ways to accomplish a task. I just had added suggestion. You can choose as per requirement. SO ready to help!! – luckyShubhra Jul 26 '17 at 08:59