My application is a Tabbed Application, and it have several controllers under the tabBarController. One controller is a navigationController, and its root view is a table view. When I click a row of the table view, another view will be pushed in.
So the question is that when the view is pushed in, how can I hide the tabBar at the bottom?
Besides, I also want to add another tabBar into the pushed view, so I need to alloc a UITabBar or UITabBarController? Or there is another way? Thank you!
use this methood in the UIViewController class where you want to hide the tabBarController
-(BOOL)hidesBottomBarWhenPushed
{
return YES;
}
Update
As suggested by #Yuchen Zhong in his answer, This option is now available in the storyboard itself.
You can do this in storyboard now:
Select the UIViewController in your storyboard
Select the checkbox Hide Bottom Bar on Push
Set UIViewController.hidesBottomBarWhenPushed = YES when you want hide tab bar.
nextViewController.hidesBottomBarWhenPushed = YES;
Sometimes the hidesBottomBarWhenPushed method hides the bottom bar with a choppy animation.
Instead I hide the tabbar in viewDidLoad with
self.tabBarController.tabBar.hidden = YES;
and restore its presence in viewWillDisappear
self.tabBarController.tabBar.hidden = NO;
Set true hidesBottomBarWhenPushed in the controller that you want to hide.
For hide all controllers put into prepare for segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
segue.destination.hidesBottomBarWhenPushed = true
}
Related
I am working on a new project of mine and am looking for what the best solution to keep the UITabBarController displaying even when using a segue to push to a UIViewController.
Currently I have an Initiation of our UITabBarController on app launch, which contains multiple viewcontroller relationships. Particularly the initial view controller option is a custom UIViewController which implements a UITableView. Once a cell is selected I call a show(push) segue to another UIViewController. This is where I lose my TabBar which is as expected. Now I have tried different approaches such as setting the hidden value of our tabbar to YES, but does not seem to help.
Code
When Cell Selected:
[self performSegueWithIdentifier: #"tableCellOptions" sender: self];
When preparing for segue:
if([segue.identifier isEqualToString:#"tableCellOptions"]) {
additionUITableView *move = (additionUITableView *) segue.destinationViewController;
move.thisOption = [menuOptions objectAtIndex:cellPushed];
}
What would your approach be to this and why?
If you have Tab bar controller as the initial View Controller, the tab bar will show by default on each view controller.
If you are using storyboard or xib file, then select the tab bar item in view controller and check its properties, and make sure "hide tab bar on push" is unchecked.
Programmatically you can do this,
self.hidesBottomBarWhenPushed = NO;
[self.navigationController pushViewController:viewControllerToPush animated:YES];
Place it in viewDidLoad or viewDidAppear.
I hope this solves your problem.
I'm developing an app displaying a table of events that are fetched from the iOS Calendar. When a row in the table is clicked, I want to display the event info using an EKEventViewController. Here is what the table of events look like:
When an event in this list is clicked, I push an EKEventViewController using the following code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
EKEventViewController *eventViewController = [EKEventViewController new];
eventViewController.event = [self.events objectAtIndex:[indexPath row]];
[self.navigationController pushViewController:eventViewController animated:YES];
[self.navigationController setNavigationBarHidden:NO];
[tableView reloadData];
}
I get to the event information screen (exactly what I want):
But when I now click the back button in the upper left corner I am met with this screen:
Notice the white bar at the bottom. To get rid of this bar I now have to kill the app, going back to the main menu and other parts of the app has no effect (every screen is just "shrunk" to fit into the now smaller space, probably because the use of auto layout).
This does not happen on iOS 7, where this white bar never appears, only on iOS 8 (8.2 tested). What is this bar and how to get rid of it?
EDIT: I notice that the "white" bar looks gray when the screenshot is posted here on StackOverflow, while it is definitely white on the device.
EDIT2: Picture of the constraints for the bottom button:
I never found out what the white bar really was, but I ended up presenting the EKEventViewController modally instead, which works very well: How to get a “Done” or “Back” button in an EKEventViewController when no having a navigation bar?
Another way to address this is through the storyboard.
Create an ViewController Object on the storyboard
Make its class EKEventViewController (No code or class file needed)
Embed in a Navigation Controller.
Create a detail segue from the view controller you wish to call the EKEventViewController to the NavigationController
Then use performSegueWithIdentifier("EKEventViewController", sender: sender)
Setup the prepareForSegue something like this....
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "EKEventViewController" {
let controller = (segue.destination as! UINavigationController).topViewController as! EKEventViewController
controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem()
controller.navigationItem.leftItemsSupplementBackButton = true
controller.event = event
controller.allowsEditing = true
self.splitViewController?.toggleMasterView()
}
}
I finally figured out what is happening in this situation. I don't normally work with UIToolbar, which is why I didn't recognize this sooner, but UINavigationController has an optional toolbar and has a function setToolbarHidden().
From the section Displaying a Toolbar
A navigation controller object manages an optional toolbar in its view hierarchy. When displayed, this toolbar obtains its current set of items from the toolbarItems property of the active view controller. [...] If not all of your view controllers support toolbar items, your delegate object can call this method to toggle the visibility of the toolbar during subsequent push and pop operations.
So in viewWillAppear() of the view controller that pushes EKEventViewController, call:
self.navigationController?.setToolbarHidden(true, animated: false)
and when pushing EKEventViewController onto the stack call:
self.navigationController?.setToolbarHidden(false, animated: true).
You can adjust the animated parameters to suit your taste.
Is it possible to set-up a navigation structure using the Interface Builder, without using the standard Apple navigation bar? I want to apply the actions which open a new View Controller to my own custom buttons.
Is this is not possible, do you guys have a good place where I can start learning to do this without using the interface builder?
you have to embed navigation controller with your root view controller. For that select your view controller in your storyboard click on editor->embed in->navigationController.
In viewDidload write
self.navigationController?.navigationBar.hidden = true
have one label of size of navigation bar at the top add a button on it and write following code in it's action method
#IBAction func goToNextController(sender: AnyObject)
{
let second = self.storyboard?.instantiateViewControllerWithIdentifier("second") as SecondViewController
self.navigationController?.pushViewController(second, animated: true)
}
here secondViewController is the one which we are pushing
similarly have a label and button at the top in secondViewcontroller and write following cod e in your button's action method
![#IBAction func previousButtonTapped(sender: AnyObject)
{
self.navigationController?.popViewControllerAnimated(true)
}][2]
In IB you can change the class for the navigation bar to your own class.
If you don't use IB you can use [[UINavigationController alloc] initWithNavigationBarClass:[MyNavBar class] toolbarClass:nil]
I am trying to do the following.
I have a tab bar controller with 2 tabs in it. Both the tabs are navigation controller with a table view on each of them.
Now when I select one cell of the table in the first tab, I am pushing another tab bar controller, so I would like to hide the tab bar of the parent tabbarcontroller, and when I click the back button on the navigation bar I would like to see the the parent tab bar again, as I am in my parent tab bar view.
I tried hidesbottombarwhenpushed and it hides the parent tab bar controller tab bar but when I click back it doesn't brings it back.
Ok, So finally I got my answer, this is what I am suppose to do.
self.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:aViewController animated:YES];
self.hidesBottomBarWhenPushed=NO;
So basically hidesBottomBarWhenPushed = YES, and then push your view controller and then hidesBottomBarWhenPushed = NO; this works like a charm.
Thanks to eddy and his post here
The accepted answer had a problem to me.
My app had a navigation with the depth of three UIViewController.
The FirsViewController show's the UITabBar. (Correct)
The FirsViewController pushes the SecondViewController, and the SecondViewController don't show's the UITabBar. (Correct)
The SecondViewController pushed the ThirdViewController, and the ThirdViewController show's the UITabBar. (Incorrect)
The ThirdViewController popped to the SecondViewController, and the SecondViewController show's the UITabBar. (Incorrect)
The SecondViewController popped to the FirstViewController, and the FirstViewController show's the UITabBar. (Correct)
The solution for me was setting the delegate of UINavigationControllerDelegate
swift:
self.navigationController?.delegate = self
Objective-c:
self.navigationController.delegate = self;
And then implement the following delegate method
Swift:
fun navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
if fromVC.isKindOfClass(FirstViewController) && toVC.isKindOfClass(SecondViewController) {
self.hidesBottomBarWhenPushed = true;
}
else if fromVC.isKindOfClass(SecondViewController) && toVC.isKindOfClass(FirstViewController) {
self.hidesBottomBarWhenPushed = false;
}
return nil
}
Objective-c:
-(id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController*)fromVC
toViewController:(UIViewController*)toVC
{
if ([fromVC isKindOfClass:[FirstViewController class]] && [fromVC isKindOfClass:[SecondViewController class]]) {
self.hidesBottomBarWhenPushed = true;
}
else if ([fromVC isKindOfClass:[SecondViewController class]] && [fromVC isKindOfClass:[FirstViewController class]]) {
self.hidesBottomBarWhenPushed = false;
}
return nil;
}
Hope it helped.
As the Apple documentation states, you can't push a UITabBarController instance on a NavigationController. And there's a good reason for that: how do you get back from the pushed tab bar controller if you selected another item in the tab bar?
The simple answer is: don't do that, it will confuse your user. You can try swapping the first view controller for another view controller that may be a tab bar controller, but do not use the push paradigm for that: use an explicit button instead that will swap your first tab bar controller for the second one, preferably using a visual transition.
You can look at the setAnimationTransition:forView:cache: documentation for the UIView class to know how to swap, say, a tab bar controller for another:
Begin an animation block.
Set the transition on the container view.
Remove the subview from the container view.
Add the new subview to the container view.
Commit the animation block.
In this case, the container view will be the application's window.
You can also hide it using the attributes inspector when select the tabBar controller
Set hidesBottomBarWhenPushed = true in the controller that will be pushed.
For hide all controllers put into prepare for segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
segue.destination.hidesBottomBarWhenPushed = true
}
In your FirstViewController use
self.hidesBottomBarWhenPushed = true
in your SecondViewController use
override func willMoveToParentViewController(parent: UIViewController?) {
if parent == nil {
var viewControllers = self.navigationController!.viewControllers
if ((viewControllers[viewControllers.count - 2]).isKindOfClass(FirstViewController.self)) {
(viewControllers[viewControllers.count - 2] as! FirstViewController).hidesBottomBarWhenPushed = false
}
}
}
I have an application with a tab bar controller and each view contains a navigation controller. My MainWindow looks as follows: Image here http://www.freeimagehosting.net/image.php?7bc867a594.png
Everything works fine as it is but I noticed a problem when pushing a details view to the navigation controller. In the didSelectRowAtIndexPath for a tableviewcontroller that belongs to the tab bar controller (the one called Latest in the image) I am doing this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ArticleViewController *articleController = [[ArticleViewController alloc] initWithNibName:#"ArticleView" bundle:nil];
[self.navigationController pushViewController:articleController animated:YES];
[articleController release];
articleController = nil;
}
The ArticleViewController has its own tabbar because it needs to display different things. The problem is that when I push the ArticleViewController into the navigationController I see both tabbars at the bottom of the view. Is there any way I can solve this problem?
Thanks in advance
After spending hours and posting a question here I found that the solution to this problem is adding the following line after the instantiation of ArticleController.
articleController.hidesBottomBarWhenPushed = YES;
If you prefer storyboard configuration over coding there is a toggle for that. Just go destinationViewController > Attribute Inspector:
A very simple solution:
destinationViewController.hidesBottomBarWhenPushed = YES;
In your case:
articleController.hidesBottomBarWhenPushed = YES;
Hope this helps!
You can simple hide parent tabbar through storyboard .
Select viewcontroller > Attribute Inspector > check Hide Bottom Bar on Push
You can add below code in the view controller, which you are pushing.
-(BOOL)hidesBottomBarWhenPushed
{
return YES;
}
This will hide the tabbar in the pushed view controller only and as you pop the view controller tabbar remains unhide in rest all view controllers.
Swift version (3.x and above)
override var hidesBottomBarWhenPushed: Bool {
get {
return navigationController?.topViewController == self
}
set {
super.hidesBottomBarWhenPushed = newValue
}
}
Thanks
for swift 3,write the same code by you unhide the tabbar before pushviewController code like below
var frame = self.tabBarController?.tabBar.frame
frame?.origin.y = self.view.frame.size.height - (frame?.size.height)!+112
UIView.animate(withDuration: 0.2, animations: {
self.tabBarController?.tabBar.frame = frame!
})
self.navigationController?.pushViewController(viewController, animated: true)
or use just whant to unhide the tabbar u can use
viewController.hidesBottomBarWhenPushed = false
enter image description here
Go to interface builder in Xcode -> open attribute inspector and check the item 'Hide Bottom bar on Push' for view controller you don't want to show tab bar. It will work!!
Use property hidesBottomBarWhenPushed in the controller that you want to hide.
For hide, all controllers put into prepare for segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
segue.destination.hidesBottomBarWhenPushed = true
}