I have the following setup:
A tab bar app.
On one tab there is a navigation controller.
My workflow:
When I push a new viewController onto the navigation controller stack, I set the hidesBottomBarWhenPushed property.
This works great, the tab bar is "pushed" as the new view controller slides in place.
The problem:
When I pop this view controller and the root view controller is once again displayed, however, the tab bar is gone.
The navigation controller has grown to fill the space left by tab bar.
Is there a property I need to set to make the tab bar visible again?
What I have tried:
popping to the root view manually
setting (resetting) the hidesBottomBarWhenPushed for the root view
resizing the root view
resizing the view property of the navigation controller (just leaves a "white space" where the tab bat should be)
What "sorta" worked:
If I set the selected index of the tab bar controller to any other index, the tab bar appears. So I know it is still "around", but this does little to help me.
I had this problem too. I was setting -hidesBottomBarWhenPushed on the wrong view controller.
Wrong (but seems to work until you pop):
self.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:self.anotherViewController animated:animated];
Right:
self.anotherViewController.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:self.anotherViewController animated:animated];
this is the same problem i had, but i got a solution, try this
I found that hiding and then showing the tabbar immediately after the push, solves our problem
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *theItem = [items objectAtIndex:indexPath.row];
DetailController *nextController = [[DetailController alloc] initWithItem:theItem];
self.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:nextController animated:YES];
//
//[nextController setHidesBottomBarWhenPushed:YES];
self.hidesBottomBarWhenPushed=NO;
[nextController release];
}
If you're using a UINavigationController and looking for a way to just hide the TabBar (BottomBar) in one view controller, place this code in the view controller you'd like to the hide the TabBar for:
- (BOOL)hidesBottomBarWhenPushed {
return [self.navigationController.visibleViewController isEqual:self];
}
Other approaches I tried with just setting the property caused the TabBar to be hidden after pushing a new view controller from the view controller with the hidden TabBar (even after setting the property to NO).
I do something similar in my app - just calling:
[self.navigationController popToRootViewControllerAnimated:YES];
seems to do the trick and the tab bar is back - admittedly this is in response to a button press rather than the nav bar pop button. I seem to remember it worked fine when using the nav bar back button as well.
Perhaps check you are only setting a single view controller to have the hidesBottomBarWhenPushed property set to YES.
In addition to doing this:
[self.navigationController popToRootViewControllerAnimated:YES];
Initially when you do self.hidesBottomBarWhenPushed = YES;
You have to change for viewControllerToBePushed.hidesBottomBarWhenPushed = YES;
That should do the work!
Curious, I never set this value, but override it on the ViewController I want:
- (BOOL) hidesBottomBarWhenPushed
{
return YES;
}
swift:
self.hidesBottomBarWhenPushed = true
self.performSegueWithIdentifier("viewcontroller_details", sender: nil)
self.hidesBottomBarWhenPushed = false
In the view controller that appears after the one with the toolbar is popped, try this magic:
- (void)viewWillAppear:(BOOL)animated {
[self.navigationController setToolbarHidden:YES animated:YES];
}
Swift 3: From code, you have to set pushedController.hidesBottomBarWhenPushed to true.
Storyboard:
Select the pushed controller, go to Attribute Inspector, select "Hide Bottom Bar on Push" option under View Controller.
I had the same issue and I couldn't fix it with any of the suggested approaches mentioned here.
I came up with a hacky way around this problem and it works fine, although in my case MAYBE because I am working with RxSwift, the issue appears to be a race-condition so I slightly delay the pop action and reveal the tabBar manually, nevertheless it might fix your problem as well:
if self.tabBarController?.tabBar.isHidden == true {
self.tabBarController?.tabBar.isHidden = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
self.navigationController?.popViewController(animated: true)
}
} else {
self.navigationController?.popViewController(animated: true)
}
Related
I'm trying to add some navigation controller in my app, it's sth likes:
in my index page view controller, I try to initialize the navigation controller like this:
-(void)viewDidLoad{
...
//allocate a navigation controller.
myNavigationController = [[UINavigationController alloc]init];
myNavigationController.delegate = self;
myNavigationController.navigationBar.hidden = YES;
[self.view addSubview:myNavigationController.view];
[myNavigationController pushViewController:tabViewController animated:YES];
[self presentModalViewController:myNavigationController animated:YES];
}
Here, index page view controller is the root view controller of my app, it's just a common UIViewController here.
[myNavigationController pushViewController:tabViewController animated:YES];
The tabViewController here I've pushed into the navigation controller is a custom tabview controller which makes use of a container view to hold the tab button and also holds an navigation controller for tab switching.
The problem here is:
myNavigationController.navigationBar.hidden = YES;
since I've make the navigation bar invisible, it doesn't show when my custom view controller shows, but when I'd like to switch to some other view controller with the navigation controller and I also want the navigation bar visible:
myNavigationController.navigationBar.hidden = NO;
MyViewController *toSwitchNC = [[MyViewController alloc]init];
[myNavigationController pushViewController:toSwitchNC animated:YES];
The navigation bar would never show any more. I've also tried to put:
self.navigationController.navigationBar.hidden = NO
in MyViewController's viewDidLoad, ViewDidAppear or even in the navigation controller's delegate method, it didn't show the navigation bar neither.
So what's wrong with it? Why I initialized the navigation bar to be invisible at first, it will never show again even I set the hidden flag to be false?
Okay, I've got this fixed by removing the navigation controller container in my index page view controller. This might be a stupid question, since apple've formally stated in the developer document that the navigation view controller should be place as root as possible in the view stack. Since IOS is a closed system, who knows WTH is going on under-beneath except Apple.
I have an app which consists of three layers of view controllers: UITabBarController => UINavigationController => UIViewController. They are all generated in code rather than using IB. The tab bar is on the bottom as per the usual design guidelines. In my UIViewController I am using this code to present the modalViewController:
myModalVC = [[MyModalViewController alloc] init];
[self.navigationController presentModalViewController:myModalVC animated:YES];
This work fine and the modal view controller pops up and covers the entire screen.
However when a button is pressed within the modal view controller, I run this:
[self dismissModalViewControllerAnimated:YES];
And the modal view controller animates away. However I can see the original UIViewcontroller view but the tab bar disappears completely. I've googled a lot but I can't find anyone that has this same problem.
You should delegate your modal view controller to your parent view controller. [self dismissModalViewControllerAnimated:YES]; should be done by the delegate and not the modal view itself, parent view are responsible for dismissing the modal view.
Actually I found this by googling a bit more. I made my tab bar controller a property of the app delegate and when it presents the modal vc, it does this
UIApplication *myApp = [UIApplication sharedApplication];
noIBAppDelegate*appDelegate = (noIBAppDelegate*)myApp.delegate;
[appDelegate.tabBarController presentModalViewController:myModalVC animated:YES];
Then it dismisses it by this bit of code
UIApplication *myApp = [UIApplication sharedApplication];
noIBAppDelegate*appDelegate = (noIBAppDelegate*)myApp.delegate;
[appDelegate.tabBarController dismissModalViewControllerAnimated:YES];
This fixes the the tab bar disappearing.
Try
[self.navigationController dismissModalViewControllerAnimated:YES];
Thanks for your answer! I had the same problem, but I'm writing in Swift, so thought I'd include my solution that I figured out from looking at yours. I only had to use these two lines to fix the problem. Nothing else was needed.
tabBarController?.presentViewController(viewController, animated: true, completion: nil)
and
tabBarController?.dismissViewControllerAnimated(true, completion: nil)
I should also mention that the line: tabBarController?.delegate = self, is in the viewDidLoad function of my NavigationController.
In my Main Window IB file I have a TabBarController and the first controller is a Navigation Controller. When I push my detail view (after pressing a cell in a table view) I want to push my detail view and display a tool bar instead of the tab bar. The problem is that when I try
tabBar.hidden = visible;
in my detail view controller (viewDidLoad) the tabbar dissapears before the animation between the first view and the detail view is done.
What i want to achieve can be seen in the native photo app when pressing on one of the images from a gallery. There the tabbar moves out with the animation of the first view.
How do I achieve this?
Thanks in advance
check out the 'hidesBottomBarWhenPushed' property on your detail's page subclass of UIViewController
either override this method
- (BOOL)hidesBottomBarWhenPushed
{
return YES;
}
or i'm guessing this would work the same:
self.hidesBottomBarWhenPushed = YES;
as far as showing the toolbar try:
- (void)viewWillAppear:(BOOL)animated
{
[self.navigationController setToolbarHidden:NO animated:YES];
}
and on the way out
- (void)viewWillDisappear:(BOOL)animated
{
[self.navigationController setToolbarHidden:YES animated:YES];
}
I've been wandering how to hide / remove / disable only the main or first navigation bar in the navigation controller so that I could put an image as a whole background screen but I couldn't find any solution.
Did try hide the titleview in viewdidLoad of the main navigation controller but didn't work. Tried using navigationBarHidden but it hides the whole navigation bar for the next stack of controller.
So, I'm not sure how to do this. To give you an example, I would like to have something like this app - The Masters Golf Tournament - http://appshopper.com/sports/the-masters-golf-tournament.
If you look at Screen 1, it doesn't have any nav bar at the top but when you touch any options it will push to a new view controller and have the nav bar appear as in Screen 3,4 and 5.
Hope anyone could help me with this.Thanks a lot!
In most of my applications I have a custom UIViewController class that I derive all other custom controllers from. In some of these, I added a method like navigationBarInitiallyHidden to the base class that other classes can override. The default result depends on the nature of the application.
In the delegate of the navigation controller, when a controller is being shown that implements that method, the delegate hides or shows the navigation controller accordingly. Since I animate the hide or show, I check the current state and do nothing if no change is needed.
You could do something simpler in your delegate method. If the controller being shown is the root controller, hide the navigation bar, otherwise show it if it is hidden.
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if ( viewController == rootController ) {
[navigationController setNavigationBarHidden:YES animated:animated];
} else if ( [navigationController isNavigationBarHidden] ) {
[navigationController setNavigationBarHidden:NO animated:animated];
}
}
You can hide the navigation bar:
[self.navigationController setNavigationBarHidden:YES];
and where you want to show the navigation bar again
[self.navigationController setNavigationBarHidden:NO];
hide/disable
self.navigationController.navigationBarHidden = YES;
show/Enable
self.navigationController.navigationBarHidden = NO;
You can hide navigation bar by using bellow code. Below code will hide navigationbar at the time of viewWillAppear.
Objective C
-(void)viewWillAppear:(BOOL)animated
{
[[self navigationController] setNavigationBarHidden:YES animated:NO];
}
Swift
self.navigationController?.setNavigationBarHidden(true, animated: animated)
I'm changing the back button item title in the viewDidAppear of a controller in the following way:
self.navigationController.navigationBar.backItem.title = #"Previous";
It changes the tittle properly, but the I'm having a strange behaviour. When I select the "previous" button, it changes the tittle of the controller that is up in the stack (i.e the parent controller now has the title "Previous".
Do you now why this happened?
When you're using a navigation controller, calling [self setTitle:#"Title"]; inside of any view controller in the stack will set the navigation bar title. This is also the title used by default for the back button when you've pushed a new view controller. Apparently, from what you are experiencing, explicitly setting the title of the backItem, also sets it for the navigation bar title for the previous view controller overriding whatever what specified in the call to -setTitle in the view controller.
You will probably be better off just managing the title from within the view controllers in your navigation stack. When you go to push a new view controller, do this:
[self setTitle:#"Previous"];
NextViewController *controller = [[NextViewController alloc] init];
[[self navigationController] pushViewController:controller animated:YES];
[controller release], controller = nil;
Now, when the next view controller displays, the back button with say "Previous". Now, you just need to change it back to whatever its real title should be in -viewWillAppear:
- (void)viewWillAppear:(BOOL)animated;
{
[self setTitle:#"Real Title"];
[super viewWillAppear:animated];
}
It may feel a little hacky, but it's better than trying to override the navigation bar functionality. Wrestling with the nav bar/nav controller stack can prove very frustrating.
Best regards.