How does one hide the UITabBar programmatically? It's been asked and answered multiple times on SO, but the answers seem to come in roughly two varieties:
1) Using a navigation controller, one can hide the next vc's tab bar before the push using hidesBottomBarWhenPushed property. Typical answer here.
2) Walk through the tabbar controller's view hierarchy and modify the tab bar's frame and/or visibility. Typical answer here.
But both sorts of answers fall short, imo. 1) What if we need to hide the tab bar on the view we are on, say when rotating to landscape. 2) A half page of code waking through an Apple library's private view hierarchy is a. cumbersome, b. prone to unforseen breaking, c. possibly a blocker for app approval.
So what's an app to do? Is the answer that it's not allowed? Is there an apple document ref supporting that? It would be a sad answer. Imo, the rotation case is a legitimate reason for hiding the tab bar.
Thanks in advance for your help.
Sorry for the delayed response but I've pulled my code and you can see how I rotate my device to show a 'Map View' in full screen in landscape only.
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if(toInterfaceOrientation == UIInterfaceOrientationLandscapeRight || toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
[self hideTabBar:self.tabBarController];
[self.view bringSubviewToFront:self.eventsMapView];
self.eventsMapView.bounds = self.view.bounds;
self.eventsMapView.frame = CGRectMake(0, -208, self.view.frame.size.width, 300);
} else if(toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown || toInterfaceOrientation == UIInterfaceOrientationPortrait) {
[self showTabBar:self.tabBarController];
[self.view sendSubviewToBack:self.eventsMapView];
}
}
And since we call methods within that to actually hide and show the tab bar, we need to define those methods in our .m file as well:
#pragma mark - Tab Bar Methods -
-(void)hideTabBar:(UITabBarController *)tabbarcontroller {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
for(UIView *view in tabbarcontroller.view.subviews) {
if([view isKindOfClass:[UITabBar class]]) {
[view setFrame:CGRectMake(view.frame.origin.x, 480, view.frame.size.width, view.frame.size.height)];
} else {
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 480)];
}
}
[UIView commitAnimations];
}
-(void)showTabBar:(UITabBarController *)tabbarcontroller {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
for(UIView *view in tabbarcontroller.view.subviews) {
if([view isKindOfClass:[UITabBar class]]) {
[view setFrame:CGRectMake(view.frame.origin.x, 431, view.frame.size.width, view.frame.size.height)];
} else {
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 431)];
}
}
[UIView commitAnimations];
}
If you're already within a Tab Bar Controller then you need to make sure every child (or individual tab ViewController) returns TRUE for orientation like below.
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return TRUE;
}
Hope this helps - if you have any questions leave a comment and I'll update my answer to show it off better.
You can find some useful code here. You can call hideTabbar from your shouldrotate: method
2021 answer. Xcode 12.
Create a new layout for when in Landscape mode. in the below picture, I created wAny hCompact (hC) attribute and then set it as hidden.
Related
i am having one problem in iOS project,i need to hide my tab bars during login function and like to show my tab bars after login.I have searched many contents no one is working for my project.Please give me the solution with detailed procedure like where and what i want to develop .in my project app delegate function has
tabView = [[GTabBar alloc]initWithTabViewControllers:viewControllersArraytabItems:tabItemsArray initialTab:1];
[window addSubview:tabView.view];
[window makeKeyAndVisible];
GTabBar ->for creating Tab Bar.
viewcontroller array ->list of view controllers.
tabitems array->list of tab items.
apart from that MainViewController is a file for handling tab events.
Thanks in advance
You can create one navigation controller and then you can create your tabbar controller and push into the same navigation controller in which loginviewcontroller has.
you can achieve that via below steps:
create login view controller
create navigation controller with login as root controller
when login process completes you just need to push whole tabbarcontroller in to the same navigation controller.
Add below methods in appdel and you can call this methods in any view controller to show and hide tabbbar. Just call this method wherever you want to show and hide tabBar.
- (void)hideTabBar:(UITabBarController *) tabbarcontroller
{
// [UIView beginAnimations:nil context:NULL];
// [UIView setAnimationDuration:0.1];
for(UIView *view in tabbarcontroller.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, ([UIScreen mainScreen].bounds.size.height == 568.0 ? 568:480)+20, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, [UIScreen mainScreen].bounds.size.height == 568.0 ?568: 480)];
}
}
// [UIView commitAnimations];
}
- (void)showTabBar:(UITabBarController *) tabbarcontroller
{
for(UIView *view in tabbarcontroller.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, ([UIScreen mainScreen].bounds.size.height == 568.0 ? 519:431), view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, [UIScreen mainScreen].bounds.size.height == 568.0 ? 519:431)];
}
}
// [UIView commitAnimations];
}
Login should become another workflow outside your main flow. So you should use tabbarController as main controller and login flow will be shown by presentation control
[tabbarController presentModalViewController:loginController animated:YES];
Currently I have a setup with firstTabViewController hosting 5 buttons each loading a table view. When a user selects one of the table cells it opens a secondTabViewController with a set of 4 different tab buttons. I am also embedding a navigation controller.
I have set it up via storyboard and have come up with some issues. Firstly when it loads the secondTabViewController it loads it within the firstTabViewController so I have 2 sets of tab buttons on top of each other. If I change the segue to modal it loads the secondTabViewController correctly but doesn't allow me to use the navigation controller to go back.
Is there a solution to this or should I stop wasting my time with using storyboard and rather just set it up programmatically?
Screenshot: Storyboard
I use this code when I want to hide a tabbar:
I forgot where I stole it from but I'm pretty sure it was here on SO.
- (void) hideTabBar:(UITabBarController *) tabbarcontroller {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
for(UIView *view in tabbarcontroller.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, 480, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 480)];
}
}
[UIView commitAnimations];
}
- (void) showTabBar:(UITabBarController *) tabbarcontroller {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
for(UIView *view in tabbarcontroller.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, 431, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 431)];
}
}
[UIView commitAnimations];
}
Use your original strategy and then hide the first tab view controller's tab bar when you open your second tab bar view.
I have several view controllers for various parts of a game I am working on, let's call them screens 1,2,3,4.
I would like to be able to start the game up in screen 1, then show 2, 3, 4 and then go back to screen 1 and start all over again (sometimes I want to leave out #3, etc). I have managed to get this functionality with the UITabBarController but I couldn't figure out how to hide the tab control itself. If I hid the actual control it would just display a white bar in its place. If I tried to resize the view it worked on the first screen, then the others appeared to be twice the screen size (set in viewWillAppear):
[[self view] setFrame:[[UIScreen mainScreen] bounds]];
Has anybody managed to get this sort of thing working? Would I be able to use a navigation controller to do this?
I suggest you to use UINavigationController for this because for your purpose this can be done with UINavigationController instead of UITabBarController.
But if you want to continue with UITabBarController then you can hide your UITabBarController by calling this method in your app delegate:
- (void) hideTabBar:(UITabBarController *) tabbarcontroller {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
for(UIView *view in tabbarcontroller.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, 480, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 480)];
}
}
[UIView commitAnimations];
}
developers!
Im currently working on an app that uses the Tab Bar Application template. What I wanna do
is to simulate a startpage for my app that corresponds to the first tab.
So when the app start the first tab is selected and the UITabBar should not be visible.
In this "startview" there is multiple buttons that acts like the rest of the tabs, so for instance i press button #2 and the second tab view is pushed and the UITabBar is again visible.
My problem is that i have a way to hide the bar but the subview is not resizing to fullscreen.
By using:
[self.tabBarController.tabBar setHidden:YES];
I've also tried to use:
self.hidesBottomBarWhenPushed = YES;
But it seems to have no effect and I'm not sure where to add the code since I'm using
the template.
Anyone knows how to implement this by using the Tab Bar Application template?
I'm guessing it should be at the:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController: (UIViewController *)viewController
But I've tried that and that method is never being called...
Many thanks,
Robert
THis code may help you to Hide tabbarcontroller and resize the viewcontroller.
- (void) hideTabBar:(UITabBarController *) tabbarcontroller {
int height = 480;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
for(UIView *view in tabbarcontroller.view.subviews) {
if([view isKindOfClass:[UITabBar class]]) {
[view setFrame:CGRectMake(view.frame.origin.x, height, view.frame.size.width, view.frame.size.height)];
}
else {
[view setFrame:CGRectMake(view.frame.origin.x,view.frame.origin.y, 320, 436)];
}
}
[UIView commitAnimations];
}
This second method may help you to set tababr again in view
- (void) showTabBar:(UITabBarController *) tabbarcontroller {
int height = 480;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
for(UIView *view in tabbarcontroller.view.subviews) {
if([view isKindOfClass:[UITabBar class]]) {
[view setFrame:CGRectMake(view.frame.origin.x, height, view.frame.size.width, view.frame.size.height)];
}
else {
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, height)];
}
}
[UIView commitAnimations];
}
please understand code before implementing it in your code...
I am trying to hide the tabbar controller and display uiimageview similar to how it is done in native photo library of iphone. I have already created the library but I am having problem in displaying the images on next view by hiding tabbar. I am able to hide the tabbar but when I try to add the uiimageview it does not expend to space taken up by tab bar. I want my uiimageview to stretch till bottom of the screen.
I even want to add a button on that empty space but I am not able to do it.
My code to hide tab bar:
self.tabBarController.tabBar.hidden = YES;
Can some one please help me?
Thanks
Pankaj
Try this
self.tabBarController.tabBar.hidden = YES;
and
[imageView setFrame:CGRectMake(0,0,320,480)];
just use below two methods to hide or show tabbar controller. put this methods in delegate class so it's easy to call from any class.
- (void) hideTabBar:(UITabBarController *) tabbarcontroller {
int height = 480;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
for(UIView *view in tabbarcontroller.view.subviews) {
if([view isKindOfClass:[UITabBar class]]) {
[view setFrame:CGRectMake(view.frame.origin.x, height, view.frame.size.width, view.frame.size.height)];
}
else {
[view setFrame:CGRectMake(view.frame.origin.x,view.frame.origin.y, 320, 436)];
}
}
[UIView commitAnimations];
}
- (void) showTabBar:(UITabBarController *) tabbarcontroller {
int height = 480;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
for(UIView *view in tabbarcontroller.view.subviews) {
if([view isKindOfClass:[UITabBar class]]) {
[view setFrame:CGRectMake(view.frame.origin.x, height, view.frame.size.width, view.frame.size.height)];
}
else {
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, height)];
}
}
[UIView commitAnimations];
}
You need to set the frame of the bottom subview of the tabBarController's view property, like so:
self.tabBarController.tabBar.hidden = YES;
UIView* subview = (UIView*)[self.tabBarController.view.subviews objectAtIndex:0];
imageView.frame = subview.frame = self.window.bounds;
This is something I've used in some form in a couple of in-production products. Whether or not you actually want to utilize self.window.bounds depends on if your current class has a window property pointing to the mainWindow instance of UIWindow, whether you are supporting multiple orientations (bounds of window stays the same regardless of the current UIInterfaceOrientation, view controllers rotate, windows do not) and if you need to account for the status bar. If accounting for the status bar (UIStatusBar), offset the y & height by 20. Casting subview to UIView allows you to use dot syntax in this case (the static analyzer can't tell which objects are in an array).
I have been struggled on that for hours. Finally I found a solution. Just follow the following steps:
Tick the box Hide Bottom Bar on Push in your child view controller (the one you want to hide the tab bar) from Storyboard.
Add the following code in the viewWillAppear method in your root view controller: self.tabBarController?.tabBar.hidden = false.
Add the following code in the viewWillAppear method in your pushed view controller: self.tabBarController?.tabBar.hidden = true.
That's all. It just works!