Add controller to UITabBarController without new item appearing in the tab bar - ios

I have an application with UITabBarController as its main controller.
When user taps a button(not in the tab bar, just some other button), I want to add new UIViewController inside my UITabBarController and show it, but I don't want for new UITabBarItem to appear in tab bar. How to achieve such behaviour?
I've tried to set tabBarController.selectedViewController property to a view controller that is not in tabBarController.viewControllers array, but nothing happens. And if I add view controller to tabBarController.viewControllers array new item automatically appears in the tab bar.
Update
Thanks to Levi, I've extended my tab bar controller to handle controllers that not present in .viewControllers.
#interface MainTabBarController : UITabBarController
/**
* By setting this property, tab bar controller will display
* given controller as it was added to the viewControllers and activated
* but icon will not appear in the tab bar.
*/
#property (strong, nonatomic) UIViewController *foreignController;
#end
#import "MainTabBarController.h"
#implementation MainTabBarController
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
{
self.foreignController = nil;
}
- (void)setForeignController:(UIViewController *)foreignController
{
if (foreignController) {
CGFloat reducedHeight = foreignController.view.frame.size.height - self.tabBar.frame.size.height;
foreignController.view.frame = CGRectMake(0.0f, 0.0f, 320.0f, reducedHeight);
[self addChildViewController:foreignController];
[self.view addSubview:foreignController.view];
} else {
[_foreignController.view removeFromSuperview];
[_foreignController removeFromParentViewController];
}
_foreignController = foreignController;
}
#end
The code will correctly set "foreign" controller's view size and remove it when user choose item in the tab bar.

You either push it (if you have a navigation controller) or add it's view to your visible View Controller's view and add it as child View Controller also.

You can either present the new view controller with:
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion;
Or, if one of your UIViewControllers is inside a UINavigationController, you can:
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;

Related

Tab bar is hidden in iOS

I have a tab bar controller with four tabs. For one tab, i have created a new storyboard with navigation view controller and simple UIViewController. For other tabs, connected view controllers with navigation controller within the same storyboard.
When i try to launch first view controller from new storyboard from first tab, it is not showing tab bar. for others it is showing tab bar properly.
-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
NSInteger index = [tabBar.items indexOfObject:item];
if(index == 0){
UIViewController *suggestionsViewCintroller = (UIViewController *)[[UIStoryboard storyboardWithName:#"suggestions_view" bundle:nil] instantiateViewControllerWithIdentifier:#"suggestions_view_controller"];
[self addChildViewController:suggestionsViewCintroller];
[self.view addSubview:suggestionsViewCintroller.view];
suggestionsViewCintroller.hidesBottomBarWhenPushed = NO;
[suggestionsViewCintroller didMoveToParentViewController:self];
}
}
Navigation controller configuration in storyboard :
View controller and tab bar controller are in different storyboards.
Why is it not showing tab bar in view?
I don't think that is the proper way to add a view controller to the tab bar. I think you want to sub class your UITabBarController and add the new view controller to the UITabBarController sub class in the viewDidLoad method of the sub class. You can see an example of this here. The main code is added in TabBarController (a sub class of UITabBarController)
- (void)viewDidLoad {
[super viewDidLoad];
UINavigationController* naviController = [[UIStoryboard storyboardWithName:#"Other" bundle:nil]
instantiateViewControllerWithIdentifier:#"NavigationController"];
naviController.tabBarItem = [[UITabBarItem alloc] initWithTitle:#"Suggestions"
image:[UIImage imageNamed:#"suggestions"] tag:2];
self.viewControllers = [self.viewControllers arrayByAddingObject:naviController];
}
Edited the example to use 2 different storyboards.
Main storyboard:
Other storyboard:
Video here.
Calling 'addChildViewController' you do not add tab in UITabBarController.
This call just add child view controller over whole view of UITabBarController. So it is quit reasonable, that you can not see tabbar.
If you wish to add view controller as TAB of UITabBarController, you should use 'viewControllers' property as shown here:
https://stackoverflow.com/a/11399634/4322841
And should maybe use 'selectedIndex' property.

How to keep the tab bar hidden while switching between more than 5 tabs

I have a UITabBarController as my root view controller for my app. It has 6 tabs but the app has a custom popup view with 6 buttons used to selected each of the tabs. The tab bar itself is hidden at all times.
The problem is once I try to programmatically select a tab at index 5 or 6 I get an issue. Tabs 1-4 are fine, they get selected in code and the new view controller appears on screen. But since tabs 5 & 6 are technically in the "more" tab, the tab bar appears briefly, shows animation to select the "more" tab and then disappears again. This also puts these "extra" view controllers in a new navigation controller with the "more" table view as the root view controller. This adds a new navigation bar and causes other issues.
Is there any way to do any of the following?
Have more than 5 tabs in a tab bar without the "more" tab.
Disable the "more" tab bar selection animation and the addition of the associated navigation controller.
Create a simple custom controller that could replace the UITabBarController entirely.
It seems like there are a lot of situations where one would want to show more than 5 tabs and yet hide the tab bar but I couldn't find anyone discussing this issue.
According to your requirements, I think you need a custom tabar controller.
This project may help you:
RDVTabBarController
Besides, I must warn you that using custom tabbar controller you may lost the chances to use the convenient features that system tabber contrller provides.
You should use the custom tabbar controller only if the system tabbar controler doesn't fit you needs.
Try the code below . The ViewController used here is a sub class of UITabBarController. In the .h file add ITabBarDelegate , UITabBarControllerDelegate.I guess this way you can add 6 tabs. I have done two tabs here and transition with animation. Use the delegate method
(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
as shown below to apply animations.
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
fvcontroller = [self.storyboard instantiateViewControllerWithIdentifier:#"navcontroller"];
svcontroller = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
NSMutableArray *viewcontrollers = [[NSMutableArray alloc]init];
[viewcontrollers addObject:fvcontroller];
[viewcontrollers addObject:svcontroller];
[self setViewControllers:viewcontrollers];
fvcontroller.tabBarItem = [[UITabBarItem alloc]initWithTitle:#"Me" image:[UIImage imageNamed:#"me.png"] tag:1];
svcontroller.tabBarItem = [[UITabBarItem alloc]initWithTitle:#"Chat" image:[UIImage imageNamed:#"chat3.png"] tag:2];
// _tbbar.delegate = self;
self.delegate = self;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
UIView *from = self.selectedViewController.view;
UIView *to = viewController.view;
NSInteger fromindex = [self.viewControllers indexOfObject:self.selectedViewController];
NSInteger toindex = [self.viewControllers indexOfObject:viewController];
[UIView transitionFromView:from
toView:to
duration:.5
options:UIViewAnimationOptionTransitionFlipFromBottom
completion:^(BOOL finished) {
if (finished) {
tabBarController.selectedIndex = toindex;
}
}];
//(toindex > fromindex ? UIViewAnimationOptionTransitionCurlUp : UIViewAnimationOptionTransitionCurlDown)
return NO;
}
#end

Which NavigationController Method runs on every view reload (TabBarItem)

I have a NavigationController then a TabBarController which has Four Tabs.
I wanted to display Different titles on TopBar when a Different Tab is selected.
One way was to Embed each TabBarItem View into Navigation Controller but for some reason this doesn't seems the correct way, i wanted to apply this via code.
I managed accomplish this by using this code: (Products_ViewController.m custom class)
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UINavigationController *navCon = (UINavigationController*) [self.navigationController.viewControllers objectAtIndex:0];
navCon.navigationItem.title = #"Products";
}
But the problem is now when a tab is clicked First time, it changes the title but then it doesn't. I then applied the same code on -(void)viewDidAppear{} but still the same result.
How can i manage to display navigation top bar title (or run the above code) whenever the tab bar item is clicked or the view is shown?
Thanks!
You could implement the UITabBarControllerDelegate in the Products_ViewController.m class and execute your code in the tabBarController:didSelectViewController: method.
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
UINavigationController *navCon = (UINavigationController*) [self.navigationController.viewControllers objectAtIndex:0];
navCon.navigationItem.title = #"Products";
}
In the viewDidLoad method you have to set the delegate to self.

How to eliminate back bar button animation in a UISplitViewController app?

In a non-IUSplitViewController app, I am able to suppress the default back bar animation by adding this to my UIApplicationDelegate class header:
#interface MyNavigationBar : UINavigationBar { } #end
#interface MyNavigationController : UINavigationController { } #end
along with this in the corresponding .m:
#implementation MyNavigationController
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
{
return( [super popViewControllerAnimated:NO] );
}
#end
#implementation MyNavigationBar
- (UINavigationItem *)popNavigationItemAnimated:(BOOL)animated
{
return( [super popNavigationItemAnimated:NO] );
}
#end
Of course I also assigned the Navigation Controller and Navigation Bar objects in MainWindow.xib to MyNavigationController and MyNavigationBar respectively in Interface Builder.
This works like a charm in a standard application.
My problem is achieving the same thing in a UISplitViewController app.
Specifically, I cannot figure out how to override the default behavior of UINavigationBar in that case in order to suppress animation of the navigation bar when a view controller is popped via the back bar button.
I can override the behavior of UINavigationController by doing this whenever I instantiate a UIViewController as the root of the UISplitViewController right pane:
[split is a pointer to my UISplitViewController]
MyNavigationController *nc = (MyNavigationController *) [split.viewControllers objectAtIndex:1];
nc = [[[MyNavigationController alloc] initWithRootViewController:someController] autorelease];
split.viewControllers = [NSArray arrayWithObjects: [split.viewControllers objectAtIndex:0], nc, nil];
split.delegate = someController;
To recap, when I hit the back bar button in my UISplitViewController app, the content area of the active view controller does not animate when popped via the back bar button, but the navigation bar does animate, which looks dopey.
I found the solution for the standard application case in this forum, but saw no mention of a UISplitViewController solution.
I tried overriding initWithCoder in MyNavigationController to assign an instance of MyNavigationBar to the navigationBar attribute, but it wouldn't let me since it is read-only.
Stumped.

IOS go to specific view from tabbar controller from other view

I have a view with 3 buttons and a tabbar controller that contains 3 views. I am using the storyboard. I want go from my view to a specific view from the tabbar controller. When I create a segway to the destination view, the tabbar is not included.
The only way I find out is to create a segway to the tabbar controller itself, but then by default the first view is been shown.
Thanks in advance!
Yess!! I got the solution. Do the following:
In you're .h file:
#property (strong, nonatomic) UITabBarController *tabController;
In you're .m file:
#synthesize tabController;
tabController = [self.storyboard instantiateViewControllerWithIdentifier:#"tabbar"];
The selected index is the tab you want to go
tabController.selectedIndex = 1;
[[self navigationController] pushViewController:tabController animated:YES];

Resources