hide and show left navigation bar button on demand in iOS-7 - ios

I added my left navigation bar button using the storyboard. but I want it to hide when I first load the screen. And then in response to something else, I want it to show. The navigation bar has a method for hiding the back button. But there is no method for hiding/showing the left button. Is there a simple way for doing this? Or do I have to use two methods: the hiding method creates an empty button and the showing method creates the correct button? The button in question is just the Add template that iOS provides (which makes it easy to just use the one in the storyboard than to create my own).

Here is how I solved it
-(void) hideAndDisableRightNavigationItem
{
[self.navigationItem.rightBarButtonItem setTintColor:[UIColor clearColor]];
[self.navigationItem.rightBarButtonItem setEnabled:NO];
}
-(void) showAndEnableRightNavigationItem
{
[self.navigationItem.rightBarButtonItem setTintColor:[UIColor blackColor]];
[self.navigationItem.rightBarButtonItem setEnabled:YES];
}

Swift version of #learner answer
func hideAndDisableRightNavigationItem (){
self.navigationItem.rightBarButtonItem?.enabled = false
self.navigationItem.rightBarButtonItem?.tintColor = UIColor.clearColor()
}
func showAndEnableRightNavigationItem(){
self.navigationItem.rightBarButtonItem?.enabled = true
self.navigationItem.rightBarButtonItem?.tintColor = UIColor. blackColor()
}

Here is what I did. On the initial screen I wanted to hide the navigation bar:
self.navigationController.navigationBarHidden = YES;
On the second screen I wanted to show the navigation bar so I set:
self.navigationController.navigationBarHidden = NO;

Related

iOS: possible to superimpose barbuttonitem on other barbuttonitem and swap them

I have a screen that displays some info in a textview and I would like the user to be able to edit it.
Right now, I have an edit button on the right side of the navigation bar that I create in code as follows:
UIBarButtonItem *editButton = [[UIBarButtonItem alloc] initWithTitle:#"Edit" style:UIBarButtonItemStylePlain target:self action:#selector(gotoEdit)];
self.navigationItem.rightBarButtonItem = editButton;
For editing, I could launch a new view controller but it would be cleaner, I think, to just use the textview.editable property to make the text view editable.
However, I would then need to change the title and function of the uibarbuttonitem from edit to save.
You apparently cannot change the title of a system edit button and I'd just as soon not create a custom bar button item although this may ultimately prove necessary.
It is possible to hide bar button items by making their color clear and disabling interaction. Therefore, I had the idea of putting two in the same place and hiding and showing them accordingly.
Hence my question. Is it possible to put two in the same place?
Thanks for any ideas on this.
If you are using storyboards...you can drag and drop a UIButton to the rightBarButtonItem. Make this button a property and set the initial title to "Edit".
In the Action:
- (IBAction) editButton (id){
if(!isEditing){
// Prep for editing
[self.editButton setTitle:"Save" forState:UIControlStateNormal];
isEditing = true;
}else{
// Prep for save
[self.editButton setTitle:"Edit" forState:UIControlStateNormal];
isEditing = false;
}
}

Back button covers up a previous UIBarButton when pushViewController is called

My app is navigated by a slide out menu from the left. On top of each viewController is a left UIBarButton titled "Navigation", that when touched, opens the slide out menu without having to do the drag effect. I am implementing speech commands into my app, and if a user speaks "Go to Finances", it segues to a viewController titled FianceViewController through instantiateViewController to pushViewController.
This all works fine, the only problem is the back button associated with push segue covers up my "Navigation" button in the left slot of the UINavigationBar. Using self.navigationItem.hidesBackButton = YES; hides both the back button and my "Navigation" button. Is there anyway not make a back button appear when the push happens, but still allow my previously created "Navigation" bar button to be seen and used? Or is there another type of segue that I can do other than push if this UIBarButton dilemma cannot be solved?
Section of code that segues when spoken:
if ([title isEqualToString:#"FINANCES"])
{
FinanceViewController *fvc = [[self storyboard] instantiateViewControllerWithIdentifier:#"finance"];
[[self navigationController] pushViewController:fvc animated:YES];
}
How are you adding the navigation button?
I would try to add it after hiding the back button, something like this:
self.navigationItem.hidesBackButton = YES;
UIButton *navigationButton = [[UIButton alloc] initWithFrame:CGRectMake(15.0, 15.0, 100.0, 32.0)];
self.navigationController.navigationBar.backItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:navigationButton];
Instead of hiding my back button, I figured out I could simply write over it! Using fvc.navigationItem.leftBarButtonItem = self.navigationItem.leftBarButtonItem; before pushViewController, allows the "navigation" button to override the back button.

Search Bar with Maps app behavior (navigation bar full width when selected)

I'm trying to display a search bar that would have exactly the same behavior as the one in native Maps app. I mean:
search bar in the title view of my navigation bar
when selected, the search bar occupies the full width of my navigation bar and I display the SearchDisplayController
So far, I managed to get the following behavior:
As you can see above, I can't manage to get the search bar to occupy the full width on selection. Though, full width + cancel button seems like the default behavior for search bar that are hooked with SearchDisplayController, at least if the search bar was not added to the navigation bar!
Am I missing an obvious way of doing that? Or do I have to customize the navigation bar by myself when searchBarShouldBeginEditing is called?
As long as I do not have the perfect solution, I'm doing the following. But I'm still open to something better!!
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(onCancel)];
[UIView animateWithDuration:0.1 animations:^(){
self.navigationItem.leftBarButtonItem = nil;
}];
return YES;
}
- (void)onCancel {
[self.searchController setActive:NO];
}
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar {
[UIView animateWithDuration:0.1 animations:^(){
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"OpenMenuButton.png"] style:UIBarButtonItemStylePlain target:self action:#selector(openSideMenu:)];
}];
self.navigationItem.rightBarButtonItem =self.doneButton;
return YES;
}
Besides, I'm wondering if Maps app actually use a navigation controller because there are custom behaviors (width of the titleView, animation of the leftBarButton out of the screen) that surprise me.
Are you looking for something like UISearchDisplayController + UISearchBar ?
http://petersteinberger.com/blog/2013/fixing-uisearchdisplaycontroller-on-ios-7/

iOS abnormal behavior of Navigation Bar

I have a table view A which is segued to a view B.
In A, there is a nav bar on the top, and below is the table.
When I press a row in A's table, B is pushed.
In B's viewWillAppear, I have the following code.
-(void)viewWillAppear:(BOOL)animated
{
self.wantsFullScreenLayout = YES;
[self.navigationController.navigationBar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
self.navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
}
This makes extends the view so that below the status bar, I have Nav bar and the UIView overlapped.
I also have viewWillDisappear
-(void)viewWillDisappear:(BOOL)animated
{
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
// back button was pressed. We know this is true because self is no longer in the navigation stack.
self.wantsFullScreenLayout = NO;
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"navigationbar_bg.png"] forBarMetrics:UIBarMetricsDefault];
self.navigationController.navigationBar.translucent = NO;
}
}
So when the user press back button, it will undo the fullscreen mode so that the view and nav bar won't overlap. THE ISSUE IS, when I press back button and the previous screen A is shown, strangely the table view still appears overlapped with the nav bar.
I even tried to put self.wantsFullScreenLayout = NO in A's willViewAppear but to no avail.
Shouldn't A shrink the tableview and be located under Nav bar? Can anyone let me know what is worng and how to solve this issue?
Thanks in advance!
Instead of putting the code in viewWillDisappear method, try to put the same code in the viewWillAppear method of the previous view controller.

How to hide 'Back' button on navigation bar on iPhone?

I added a navigation control to switch between views in my app. But some of the views shouldn't have 'Back' (the previous title) button. Any ideas about how to hide the back button?
Objective-C:
self.navigationItem.hidesBackButton = YES;
Swift:
navigationItem.hidesBackButton = true
The best way is to combine these, so it will hide the back button even if you set it up manually :
self.navigationItem.leftBarButtonItem=nil;
self.navigationItem.hidesBackButton=YES;
hide back button with bellow code...
[self.navigationItem setHidesBackButton:YES animated:YES];
or
[self.navigationItem setHidesBackButton:YES];
Also if you have custom UINavigationBar then try bellow code
self.navigationItem.leftBarButtonItem = nil;
In Swift:
Add this to the controller
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.setHidesBackButton(true, animated: false)
}
Use the code:
self.navigationItem.backBarButtonItem=nil;
In the function viewDidLoad of the UIViewController use the code:
self.navigationItem.hidesBackButton = YES;
Don't forget that you need to call it on the object that has the nav controller. For instance, if you have nav controller pushing on a tab bar controller with a RootViewController, calling self.navigationItem.hidesBackButton = YES on the RootViewController will do nothing. You would actually have to call self.tabBarController.navigationItem.hidesBackButton = YES
Add this code in your view controller
UIView *myView = [[UIView alloc] initWithFrame: CGRectMake(0, 0, 300, 30)];
UIBarButtonItem *btnL = [[UIBarButtonItem alloc]initWithCustomView:myView];
self.navigationItem.leftBarButtonItem = btnL;
Don't forget that we have the slide to back gesture now. You probably want to remove this as well. Don't forget to enable it back again if necessary.
if ([self.navigationItem respondsToSelector:#selector(hidesBackButton)]) {
self.navigationItem.hidesBackButton = YES;
}
if ([self.navigationController respondsToSelector:#selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
For me none of the above seemed to work, It had no visual effect. I am using storyboards with a view that is "embedded" in a navigation controller.
I then at code level add my menuItems and for some reason the "backButton" is visible when visually debugging the view hierarchy, and my menuItem Icon is displayed beneath the invisible "back button".
I tried the settings, as suggested at the various hook methods and that had no effect. Then I tried a more brutal approach and iterate over the subview which also had no effect.
I inspected my icon sizes and appeared to be ok.
After referring to he apple Human Interface Guideline I confirmed my Icons are correct. (1 pixel smaller in my case 24px 48px 72px).
The strangest part then is the actual fix...
When adding the BarButton Item give it a title with at least one character, In my case a space character.
Hopes this helps someone.
//left menu - the title must have a space
UIBarButtonItem *leftButtonItem = [[UIBarButtonItem alloc] initWithTitle:#" " <--THE FIX
style:UIBarButtonItemStylePlain
target:self
action:#selector(showMenu)];
leftButtonItem.image = [UIImage imageNamed:#"ic_menu"];
[self.navigationItem setLeftBarButtonItem:leftButtonItem];
It wasn't working for me in all cases when I set
self.navigationItem.hidesBackButton = YES;
in viewWillAppear or ViewDidLoad, but worked perfectly when I set it in init of the viewController.
try this one -
self.navigationController?.navigationItem.hidesBackButton = true
In c# or Xamarin.ios,
this.NavigationItem.HidesBackButton = true;
navigationItem.leftBarButtonItem = nil
navigationItem.hidesBackButton = true
if you use this code block inside didLoad or loadView worked but not worked perfectly.İf you look carefully you can see back button is hiding when your view load.Look's weird.
What is the perfect solution?
Add BarButtonItem component from componentView (Command + Shift + L) to your target viewControllers navigation bar.
Select BarButtonItem set Title = " " from right panel
self.navigationItem.setHidesBackButton(true, animated: true)

Resources