how to disable a navigation bar button item in iOS - ios

I have created a navigation controller. In the second view (which is pushed), I have some webservice call and placing a overlay view and setting
self.view.userInteractionEnabled = NO ;
Once web service call is complete, then I am reverting to
self.view.userInteractionEnabled = YES ;
When I do this, every other buttons except the buttons on the navigation bar are disabled. How to disable those two navigation bar button items ? (a button similar to back button, which pops to first view controller and another button which gives info about help).
I have tried using self.navigationItem.backBarButtonItem.enabled = NO. But still I am able to tap on the button and can navigate to first screen. How can I disable these two buttons ?

Try this
Recommended
self.navigationItem.leftBarButtonItem.enabled = NO;
self.navigationItem.rightBarButtonItem.enabled = NO;
Or Simply Disable by
on Edge case
self.view.window.userInteractionEnabled = NO;
Update:
Recently Apple doesn't allow the back button to enable / disable. Instead of that we can hide it.
self.navigationItem.hidesBackButton = YES;

You can do the following if you are running on Swift
self.navigationItem.rightBarButtonItem?.enabled = true
This snippet will disable the button.

Just disable your UINavigationController view and navigation bar interaction:
self.navigationController.navigationBar.userInteractionEnabled = NO;
self.navigationController.view.userInteractionEnabled = NO;
And enable it when you need it back:
self.navigationController.navigationBar.userInteractionEnabled = YES;
self.navigationController.view.userInteractionEnabled = YES;

Latest Swift: To hide the back button, you MUST use:
self.navigationItem.setHidesBackButton(true, animated: false)
Note: This can trigger a bug in the navigation bar that can cause an artifact to appear in place of a hidden back button when transitioning to a view that doesn't have a back button (or has a leftButton in its place). The artifact that appears is either ellipses "..." or the title of the previous viewController on the stack. I believe this bug to be related to the bug documented in apple's own sample code project "CustomizingUINavigationBar", CustomBackButtonViewController.m

- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.leftBarButtonItem=nil;
self.navigationItem.hidesBackButton=YES;
}

This code should work on Swift 4.2
self.navigationItem.rightBarButtonItem?.isEnabled = false
The above code will disable the button. To enable it switch the boolean to true

Updated for Swift 3:
If you want to disable a navigation bar button item OR you want to disable hole UINavigationBar i.e. all item present on navigation bar, use below lines of code;
// if you want disable
self.navigationController?.navigationBar.isUserInteractionEnabled = false
// if you want enable again
self.navigationController?.navigationBar.isUserInteractionEnabled = true
Enjoy...!

For version iOS 10.3, swift 3:
self.navigationItem.rightBarButtonItem?.isEnabled = false.

Try this code:
UIApplication.sharedApplication().beginIgnoringInteractionEvents()
This will stop user to interaction with app and after service call, write this code again:
UIApplication.sharedApplication().endIgnoringInteractionEvents()
Sure this will help.

The simplest way to truly disable a UIBarButtonItem would be as followed:
barButtonVar.isEnabled = false

I solved this by just adding a property to my viewcontroller:
#property (nonatomic, strong) IBOutlet UIBarButtonItem * RightButton;
I then connected it to the button on the storyboard.
You can then at will set its properties like:
self.RightButton.enabled=true;

One line solution
self.navigationItem.leftBarButtonItem.enabled = NO;
self.navigationItem.rightBarButtonItem.enabled = NO;

Swift 5 & iOS 13 :
To remove all left buttons or just a specified one just remove from leftBarButtonItems Array.
self.navigationItem.leftBarButtonItems = []

Navigation bar button items must be toggled by referring to them via the navigationItem property.
For example:
func setupNav() {
let saveButton = UIBarButtonItem.init(barButtonSystemItem: .save, target: self, action: #selector(onSavePressed))
navigationItem.rightBarButtonItem = saveButton
saveButton.isEnabled = false
}
func validateSave() {
saveButton.isEnabled = isConditionMet // WON'T work
navigationItem.rightBarButtonItem.isEnabled = isConditionMet // WORKS!
}

Swift 5
self.navigationItem.rightBarButtonItem?.isEnabled = true;
self.navigationItem.rightBarButtonItem?.isEnabled = false;

var menuBtn = new UIButton(UIButtonType.Custom);
menuBtn.Frame = new CGRect(x: 0.0, y: 0.0, width: 20, height: 20);
menuBtn.SetImage(new UIImage("filter"), UIControlState.Normal);
menuBtn.Alpha = 0.05f; //to set the Alpha
menuBtn.Enabled = false;
tested on Mvvmcross Xamarin.iOS only

Swift 5
It's working for Navigation controller
//Disable
self.navigationController?.navigationBar.isUserInteractionEnabled = false
//Enable
self.navigationController?.navigationBar.isUserInteractionEnabled = true

Related

how to add a UISearchBar in the middle of a NavigationBar [duplicate]

How can I show a UISearchBar in the NavigationBar?
I can't figure out how to do this.
Your help is very much appreciated.
To put searchBar into the center of navigationBar:
self.navigationItem.titleView = self.searchBarTop;
To put searchBar to the left/right side of navigationBar:
UIBarButtonItem *searchBarItem = [[UIBarButtonItem alloc] initWithCustomView:searchBar];
self.navigationItem.rightBarButtonItem = searchBarItem;
As of iOS 7, the UISearchDisplayController supports this by default. Set the UISearchDisplayController's displaysSearchBarInNavigationBar = YES to get this working easily.
Per the documentation:
Starting in iOS 7.0, you can use a search display controller with a navigation bar (an instance of the UINavigationBar class) by configuring the search display controller’s displaysSearchBarInNavigationBar and navigationItem properties.
As one commenter noted, using searchDisplayController.displaysSearchBarInNavigationBar = true ends up hiding any existing left/right bar button items.
I've found two different ways of adding a searchBar to a navigationBar using iOS7's new property on searchDisplayController.
1) Nib Based Approach
If you're using a .xib, you can set a User Defined Runtime Attribute for this value and for whatever reason, the leftBarButtonItem stays in tact. I have not tested it with a rightBarButtonItem.
2) Code (Timing Matters)
If you want to implement in code, timing seems to matter. It seems that you must add the searchBar to the navigationBar first, then set your barButtonItem.
- (void)viewDidLoad
{
...
self.searchDisplayController.displaysSearchBarInNavigationBar = true;
self.navigationItem.leftBarButtonItem = [UIBarButtonItem new];
...
}
Check out Apple's UICatalog sample code. It shows how to use the new UISearchController in three different ways: modally, in nav bar, and below the navigation bar.
Objective C code snippet for UISearchBar in NavigationBar
- (void)viewDidLoad {
UISearchController *searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
if (#available(iOS 11.0, *)) {
self.navigationItem.searchController = searchController;
} else {
self.navigationItem.titleView = searchController.searchBar;
}
}
Read more here

IOS - how to prevent button in background from being tapped?

I have a see through UIView in front of a UIButton. There are some other UIViews on the transparent UIView that the user can interact with.
How do I prevent the user from being able to click the button in the background?
I have tried to assign first responder status to the transparent UIView, but that doesn't work and doesn't make any sense because how would the user interact with the other visible UIViews on top?
just set [self.myButton setEnabled:NO]; when your transparent view is open. Enable the button when you want to allow click
self.navigationItem.rightBarButtonItem.enabled = NO;
swift version
button.isEnabled = false
for navigation bar button
self.navigationItem.rightBarButtonItem?.enabled = false
Objective -C
self.buttonName.isEnabled = YES; //button is Enabled
self.buttonName.isEnabled = NO; // button is Disabled

Resizing UISearchBar in UINavigationBar titleView doesn't work

Resizing UISearchBar in UINavigationBar titleView doesn't work.
I also got two navigation items on each side of the UINavigationBar.
#IBAction func searchButtonPressed(sender: UIButton) {
searchWrap.frame = self.resultSearchController.searchBar.bounds
searchWrap .addSubview(self.resultSearchController.searchBar)
self.resultSearchController.active = true
self.resultSearchController.searchBar.becomeFirstResponder()
if (UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad)
{
self.tableView.tableHeaderView = searchWrap
}
else
{
self.navigationItem.titleView = searchWrap
}
searchIsOn = true
searchButton.hidden = true
filterButton.hidden = true
favButtonStar.hidden = true
settingsButton.hidden = true
}
even if set the frame it automatically resizes.
Here I have created a Demo project for the above solution which you can get it from here.
Download Demo Project
What I have done?
First, I added two buttons to UINavigationBar. First button is for demo and second is for search.
When you tap on search a UISearchBar will be added to the titleView of UINavigationBar and the buttons will be removed from the UINavigationBar
I have implemented the cancel delegate of UISearchBar, when it is called I removed UISearchBar and added the earlier two buttons again.
This how you can get the full UISearchBar
I have met this issue once. And confirm that searchBar that is added as subview on titleView does not work.
titleView belongs to self.navigationController, and your searchDelegate you're using belong to self controller, that's not self.navigationController. So it can not reach into delegate even in debug.
I don't know what your aim, but if you really want to on the navigationBar, you could pretend that, make a view look like a navigationBar, and add searchBar like subview and so on.
Hope this could help.

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

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;

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