Using UITabBar and UINavigationBar - ios

I'm facing problem with using UITabBar and UINavigationBar at the same time. My intention is to have tabBar displaying my 3 tabs and navBar on each of these tabs displaying custom name and on some of these tabs additionally displaying some buttons (such as Add button).
I created view controllers in AppDelegate's didFinishLaunchingWithOptions:
AAA *vc1 = [[AAA alloc] init];
BBB *vc2 = [[BBB alloc] init];
CCC *vc3 = [[CCC alloc] init];
Created tabBar and populated it:
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = #[vc1, vc2, vc3];
Next I have added some titles and images to the tabBarItems of these view controllers which is all working fine, but than I wanted to display navigation bar on top of the application. So I created navigation controller, but I don't know what view controller I need to initiate it with. If I use vc1 and set navController as rootViewController, application displays vc1's view and shows navBar, but doesn't show tabBar.
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:vc1];
self.window.rootViewController = navController;
//self.window.rootViewController = self.tabBarController;
I tried to set tabBarController to init navController and set navController as rootViewController - in this case views, tabBar and navBAr display correctly, but I don't have navBarItems associated with views vc1, vc2, vc3.
This is how I created navBarItems (e.g. in AAA.m):
- (instancetype)init {
self = [super init];
if (self) {
UINavigationItem *navItem = self.navigationItem;
navItem.title = #"name";
}
return self;
}
What do I need to do to make it work all together? Thanks.
EDIT:
I made some modification to the code and now navigation bar is visible, but only on the view controller set in UINavigationController's initWithRootViewController method. For example in following code I can see tab bar on every view and nav bar on the vc2 only. And my intention is to have tab bar and nav bar on every of these three vc.
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:vc2];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:vc1, navController, vc3, nil];
self.window.rootViewController = self.tabBarController;

Ok, I have an approach for you...for this you need make changes in storyboard.
Here is a screenshot
Now create a class for UITabBar: class TabBarViewController: UITabBarController
Do not write anything in this class, it just for our reference.
In AppDelegate Class, method: didlaunchFinish:
let vcTabBarViewController = STORYBOARD.instantiateViewController(withIdentifier: "TabBarViewController") as? TabBarViewController
navigationController.viewControllers = [vcTabBarViewController!]
Now in your first view controller which is on 1st tab,
In viewDidLoad method:
paste these lines:
let tabBar = self.tabBarController?.tabBar
let homeTab = tabBar?.items?[0] as UITabBarItem!
let searchTab = tabBar?.items?[1] as UITabBarItem!
let myProfileTab = tabBar?.items?[4] as UITabBarItem!
homeTab?.image = UIImage(named: "home-select")!.withRenderingMode(.alwaysOriginal)
homeTab?.image = UIImage(named: "home")!.withRenderingMode(.alwaysTemplate)
searchTab?.image = UIImage(named: "search-select")!.withRenderingMode(.alwaysOriginal)
searchTab?.image = UIImage(named: "search")!.withRenderingMode(.alwaysTemplate)
I hope this will resolve your problem.

add these line of code on every controller
[self.tabBarController setTitle:#"xyz"];
self.tabBarController.navigationController.navigationBarHidden=NO;

Related

Navigation bar not accessible when using SWRevealViewController with UITabBarController

I have set Sliding menu(Rear view controller) using SWRevealViewController with a UITabBarController (front view controller). Below is the piece of code I used:
RearMenuViewController *rearViewController = [[RearMenuViewController alloc] init];
UINavigationController *rearNavigationController = [[UINavigationController alloc] initWithRootViewController:rearViewController];
UINavigationController *navTabController = [[UINavigationController alloc] initWithRootViewController:_tabBarController];
SWRevealViewController *revealController = [[SWRevealViewController alloc] initWithRearViewController:rearNavigationController frontViewController:navTabController];
revealController.delegate = self;
revealController.rightViewController = nil;
self.viewController = revealController;
self.window.rootViewController = revealController;
This works fine and I can toggle between the rear menu and tab bar items using swipe gesture.
But I am not able to set the navigation title for each tab bar item nor I can add any bar button on navigation bar. I can only see blank navigation bar for every tab bar item.
Also would like to share that I am NOT using storyboard in the project.So, I need to set the title and a bar button through code only.
Please let me know if any other info is required.
I managed to access the navigation bar for each tab bar item like this:
UINavigationController *currentNav = (UINavigationController *)self.tabBarController.parentViewController;
UINavigationItem *navItem =(UINavigationItem *) [currentNav.navigationBar.items firstObject];
navItem.title = #"Dashboard";
Need to write this in each item (view controller) of tab bar if we need to have different titles for each tab bar item.
Please let me know if there is a better way to achieve this.

navigating to ViewControllers that aren't on the UITabBar

I started using UITabBarController and it is great.
The thing is I have a few views that aren't accessed from the UITabBar
(either presented modal programatically or we want to have a button on the top to jump to them)
The thing is that I want to retain the Tab bar visible in these views.
From my understanding mixing presentViewController and UITabBarController is problematic.
How can I do that? Can I have "hidden" tab bar elements I can reference programatically?
Just to clarify with an example:
Views A,B,C,D are in the tab bar - via the storyboard - everything is peachy.
I NEED to have views E and F clickable from the top navigation (please don't suggest a sliding TabBar or a multiple line UITabBar).
I could just jump to E and F but I want the UITabBar to still be visible so the user can jump from E to A for example.
Just use the good old UINavigationController for every tab and just use [self.navigationController pushViewController:A animated:YES];
That's how the setup looks in code:
SGTabBarViewController *rootVC = [[SGTabBarViewController alloc] init];
SGFirstTabViewController *firstVC = [[SGFirstTabViewController alloc] init];
UINavigationController *navController1 = [[UINavigationController alloc] initWithRootViewController:firstVC];
SGSecondTabViewController *secondVC = [[SGSecondTabViewController alloc] init];
UINavigationController *navController2 = [[UINavigationController alloc] initWithRootViewController:secondVC];
SGThirdTabViewController *thirdVC = [[SGThirdTabViewController alloc] init];
UINavigationController *navController3 = [[UINavigationController alloc] initWithRootViewController:thirdVC];
SGForuthTabViewController *fourhtVC = [[SGForuthTabViewController alloc] init];
UINavigationController *navController4 = [[UINavigationController alloc] initWithRootViewController:fourhtVC];
rootVC.viewControllers = #[navController1, navController2, navController3, navController4];
self.window.rootViewController = rootVC;
[self.window makeKeyAndVisible];
If you want your UITabBar visible on every VC you push just use hidesBottomBarWhenPushed = NO; on it.
However, there is no way to have UITabBar visible on views presented modally.

DetailView not created in UISplitView

I want to create UISplitView programmatically after pressing a button in a view. For UISplitView, I have two view controllers called as MyTableViewController and MyDetailViewController. This is what I am doing in the action of the button:
UISplitViewController* splitVC = [[UISplitViewController alloc] init];
MyTableViewController* firstVC = [[MyTableViewController alloc] init];
MyDetailViewController* secondVC = [[MyDetailViewController alloc] init];
UINavigationController *leftNavController = [[UINavigationController alloc] init];
[leftNavController pushViewController:firstVC animated:NO];
splitVC.viewControllers = [NSArray arrayWithObjects:leftNavController, secondVC, nil];
AppDelegate * appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.window setRootViewController:splitVC];
But secondVC (the detail view) doesn't show up. It is just black. Though, the firstVC (the table view) shows up as it should be. What could be the reason?
You should take a look at using [self.storyboard instantiateViewControllerWithIdentifier:#"DetailViewIdentifier"], and set an identifier for the view controller in your storyboard. Calling init on a view controller doesn't reference the storyboard you have created, so you need to instead pull the view controller out of the storyboard. The table view worked because its layout is programmed into the UITableViewController class.

IOS Adding a TabBar Controller to a view

My IOS app has a login sequence that cannot be modified, once the sequence is complete I do the following in the app delegate
- (UIViewController*)newRootViewController {
NViewController *nView = [[NViewController alloc]
initWithNibName:#"NViewController"
bundle:nil];
UINavigationController *navVC = [[UINavigationController alloc] initWithRootViewController:nView];
[nView release];
return navVC;
}
Once in nView is it possible to add a tab bar controller or how can I replace nView with a tab bar controller.
You can create a UITabBarController then add your NViewController and other controllers to the tab bar.
NViewController *nView = [[NViewController alloc]
initWithNibName:#"NViewController"
bundle:nil];
//Create my tab bar
UITabBarController* myTabController = [[UITabBarController alloc]init];
//Add my tabs
NSArray* tabs = [[NSArray alloc]initWithObjects:nView, nil];
[myTabController setViewControllers:tabs];

Push ViewController on Top of TabBarController

I'm stuck on a problem I really don't know how to solve:
I have a TabBarController defined in my AppDelegate.
UITabBarController *tabBarController = [[UITabBarController alloc] init];
In this TabBarController i have several other NavigationControllers which have UiVieController inside:
ProgramController *programContr = [[ProgrammController alloc] init];
UINavigationController navControllerPro = [[UINavigationController alloc] initWithRootViewController:programContr];
ManualController *manualContr = [[ManualController alloc] init];
UINavigationController navControllerMan = [[UINavigationController alloc] initWithRootViewController:manualContr];
and i add the NavigationController to the TabBarController:
tabBarController.viewControllers = [NSArray arrayWithObjects:navControllerPro,navControllerMan, nil];
I set the tabBarController to the rootViewController:
self.window.rootViewController = tabBarController;
[[self window] makeKeyAndVisible];
That works fine.
Now i want to add a "Login Screen" on top of that.
I did this with:
[tabBarController presentModalViewController:navControllerLogin animated:YES];
Now the TabBarController loads its content in the background even if the LoginViewController is in front. How to load the TabBarController only if a Button is pressed on the LoginViewController?
Please help me.
The tab bar controller is loaded everytime beacuse you set it as the rootViewController.
You should set a normal viewController as the root.. and if the login was succesfull the you should call the tabBarController to be loaded.
In other words, in the appDelegate there should be only the login window.. and in the loginViewController, if the login was ok, you should call and load your tabBarController with all its controller.. using storyboard makes it a lot easier.

Resources