How do I hide/show the right button in the Navigation Bar
Asked Answered
H

18

50

I need to hide the right button in the Navigation Bar, then unhide it after the user selects some options.

Unfortunately, the following doesn't work:

NO GOOD: self.navigationItem.rightBarButtonItem.hidden = YES;  // FOO CODE

Is there a way?

Hardset answered 7/4, 2011 at 23:22 Comment(0)
D
80

Hide the button by setting the reference to nil, however if you want to restore it later, you'll need to hang onto a copy of it so you can reassign it.

UIBarButtonItem *oldButton = self.navigationItem.rightBarButtonItem;
[oldButton retain];
self.navigationItem.rightBarButtonItem = nil;

//... later
self.navigationItem.rightBarButtonItem = oldButton;
[oldButton release];

Personally, in my apps I make my nav buttons into @properties, so that I can trash & recreate them at will, so something like:

//mycontroller.h
UIBarButtonItem *rightNavButton;
@property (nonatomic, retain) UIBarButtonItem *rightNavButton;

//mycontroller.m
@synthesize rightNavButton;
- (UIBarButtonItem *)rightNavButton {
    if (!rightNavButton) {
        rightNavButton = [[UIBarButtonItem alloc] init];
        //configure the button here
    }
    return rightNavButton;
}

//later, in your code to show/hide the button:
self.navigationItem.rightBarButtonItem = self.rightNavButton;
Durative answered 7/4, 2011 at 23:57 Comment(4)
Your property method seems like the right solution. Thanks. Question: I'm not clear how I invoke: - (UIBarButtonItem *)rightNavButton {Hardset
Sorry, another question. Is there any reason I shouldn't just recreate the button again after setting it to nil, rather than using the two methods you outline?Hardset
The rightNavButton function is the "getter" part of the property, which I have manually declared here (the "setter" is handled by synthesize). You invoke it by calling self.rightNavButton.Durative
You don't have to use the structure that I've used here, but I prefer it. As a matter of habit, anything that I'm going to need to reference at least twice somewhere in my controller logic, I create as a property. This allows me to lazy-load the object on-demand (but not before necessary) in one place. In addition, if this were, for example, a rather large UIImage, or a sound clip, and I encountered a low memory situation, I could set self.rightNavButton = nil to free up the memory, then the object would get regenerated the next time it was requested.Durative
L
19

For Swift 3

if let button = self.navigationItem.rightBarButtonItem {
                    button.isEnabled = false
                    button.tintColor = UIColor.clear
                }`
Laudian answered 23/3, 2017 at 12:3 Comment(0)
T
12

Show:

[self.navigationItem.rightBarButtonItem.customView setAlpha:1.0];

Hide:

[self.navigationItem.rightBarButtonItem.customView setAlpha:0.0];

You can even animate its showing/hiding

[UIView animateWithDuration:0.2 animations:^{
        [self.navigationItem.rightBarButtonItem.customView setAlpha:1.0];

    }];
Travistravus answered 15/10, 2013 at 7:40 Comment(1)
your solution is so perfect :DHaith
I
11

Set reference to nil:

current_controller_in_navcontroller.navigationItem.rightBarButtonItem =  nil;

Also be sure to call this in the controller currently shown by the navController, not for the navController itself.

Illtempered answered 7/4, 2011 at 23:44 Comment(1)
@lauren-quantrell you should Accept the answer if it's correct, it will help the other users reading this postIlltempered
M
8

If you have only one bar button item in the right side you can use this one,

self.navigationItem.rightBarButtonItem = nil;

Suppose if you have multiple bar button in the right side, for example suppose you have two bar button items(search button and filter button) in the right side of your navigation item. Now the right bar button items are

self.navigationItem.rightBarButtonItems = [searchItem,filterItem]

and you have to hide only search button, you can use like,

self.navigationItem.rightBarButtonItems = [filterItem]

Now what happening is, you can completely hide the search button from the navigation item and the filter item comes in the place of search item

Motoneuron answered 20/2, 2019 at 6:44 Comment(0)
C
5

Here's Matt's solution updated for Storyboards & ARC. Remember, IBOutlets are __weak by default, so you need to change that to strong for it not to be released too early.

@interface MAGTableViewController () <UITextFieldDelegate>

@property (strong, nonatomic) IBOutlet UIBarButtonItem *rightBarButton;

@end

@implementation MAGTableViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self.navigationItem setRightBarButtonItem:nil];
}

- (IBAction)rightBarButtonItemTapped:(id)sender
{
    [self.view endEditing:YES];
}

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    [self.navigationItem setRightBarButtonItem:self.rightBarButton];
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    [self.navigationItem setRightBarButtonItem:nil];
}

@end
Capillaceous answered 21/7, 2013 at 8:52 Comment(0)
M
4

Credit has to go to learner for this answer which the answer is from this question:

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

This is the answer, which is far more simple.

//hide and reveal bar buttons
-(void) hideAndDisableLeftNavigationItem
{
    [self.navigationItem.leftBarButtonItem setTintColor:[UIColor clearColor]];
    [self.navigationItem.leftBarButtonItem setEnabled:NO];
}

-(void) showAndEnableLeftNavigationItem
{
    [self.navigationItem.leftBarButtonItem setTintColor:[UIColor blueColor]];
    [self.navigationItem.leftBarButtonItem setEnabled:YES];
}

Then you just reference the method where you require it like within an (IBAction) like so:

[self hideAndDisableLeftNavigationItem];//[self showAndEnableLeftNavigationItem]; to show again

I tried all other methods and none worked, even referencing my button as a @property (...) UIBarButtonItem.... and nothing worked until I found this.

Milano answered 3/12, 2014 at 2:57 Comment(0)
Y
4

SWIFT 2.2

In swift 2.2 self.navigationItem does not work. Instead create an outlet of the NavigationItem (I named it below "nav") and use it.

Also the following suggestion did not work for me using Xcode 7.3 and swift 2.2

 nav.leftBarButtonItem?.customView?.hidden = true

So I used the idea of @Matt J above as follows (I have 2 items on the left):

  1. Create outlets for the items in the navigation bar and variables to store them

    @IBOutlet weak var settingItem: UIBarButtonItem!
    @IBOutlet weak var logoItem: UIBarButtonItem!
    
    var sav_settingItem: UIBarButtonItem = UIBarButtonItem()
    var sav_logoItem: UIBarButtonItem = UIBarButtonItem()
    
  2. Save the items in viewDidLoad()

    sav_settingItem = nav.leftBarButtonItems![0]
    sav_logoItem = nav.leftBarButtonItems![1]
    
  3. To HIDE set them to nil

    nav.leftBarButtonItem = nil
    nav.leftBarButtonItem = nil
    
  4. To SHOW them

    if (nav.leftBarButtonItem == nil) {
        nav.leftBarButtonItem = sav_settingItem
        nav.leftBarButtonItems?.append(sav_logoItem)
        return
    }
    
Yesterday answered 2/9, 2016 at 14:28 Comment(1)
it works, but it seems like you don't need the outlet.Munger
A
4

Show:

[self.navigationItem.rightBarButtonItem.customView setHidden:NO];

Hide:

[self.navigationItem.rightBarButtonItem.customView setHidden:YES];
Appurtenance answered 5/3, 2017 at 19:21 Comment(3)
Doesn't work...Scintillation
@SaadRehman sorry i don't even remember which project that i was using this technique :( I am into swift more than Objective C i would like to help if you share a sample on GitHub so we can try something together if you wishAppurtenance
Thanks man, I ended up making the button nil to hide it so its fine :)Scintillation
B
3

My solution:

self.navigationItem.rightBarButtonItem.customView.hidden=NO;
Blount answered 28/10, 2015 at 12:8 Comment(0)
G
2

Swift 2:

Trick!

Hide:

if let btn = self.tabBarController!.navigationItem.rightBarButtonItem {
        btn.enabled = false
        btn.title = ""
}

Show:

if let btn = self.tabBarController!.navigationItem.rightBarButtonItem {
        btn.enabled = true
        btn.title = "ButtonName"
}
Gesticulation answered 15/3, 2017 at 11:18 Comment(0)
A
2

You can use below code:

    self.navigationItem.rightBarButtonItem?.image = nil
    self.navigationItem.rightBarButtonItem?.isEnabled = false
Amusement answered 18/5, 2019 at 11:18 Comment(0)
P
2

For swift 5 to hide rightBarButtonItem

self.navigationItem.rightBarButtonItem?.customView?.isHidden = true
Palla answered 1/8, 2019 at 6:14 Comment(0)
S
1

In swift 4 I has a trick to show / hide right or left button:

Step 1: Create a IBOutlet button in view controller:

@IBOutlet var navigationItemButton: UIBarButtonItem!

Step 2: Create Hide button function:

func hideNavigationButton() {
    navigationItemButton.isEnabled = false
    navigationItemButton.tintColor = UIColor.clear
}

Step 3: Create Show button function:

func showNavigationButton() {
    navigationItemButton.isEnabled = true
    navigationItemButton.tintColor = UIColor.white
}

Step 4: Just call the functions that you want, use hideNavigationButton() to hide, and showNavigationButton() to show the button.

Regards!

Schizont answered 27/10, 2018 at 19:36 Comment(0)
D
0

Show:

//set navigationItem tint color white
self.navigationItem.rightBarButtonItem.tintColor = [UIColor whiteColor];

Hide:

//set navigationItem tint clear white
self.navigationItem.rightBarButtonItem.tintColor = [UIColor clearColor];
Durmast answered 19/9, 2014 at 7:34 Comment(3)
While this gives the illusion that it is hidden, it does not disable the functionality of it. I do believe that that is the desired effect.Milano
This is not a proper solution.. if user click on that portion the button action will execute...Palla
I have to agree..this is not an answer.Overweary
A
0

To hide:

if let topItem = self.navigationController?.navigationBar.topItem {
    topItem.rightBarButtonItem = nil
}
Athey answered 23/2, 2017 at 14:38 Comment(0)
C
0
  1. Assume you can reference the specific bar button as variable xxxButton

(please open Assistant Editor, Control+Drag xxx button to YourViewController class as outlet "xxxButton").

or you can use something like let xxxButton = navigationBar.buttons[1]

  1. Hide xxxButton.customView = UIView() or navigationItem.rightBarButtonItems?.remove(at: (navigationItem.rightBarButtonItems?.index(of:xxxButton)!)!)

  2. Show xxxButton.customView = nil or navigationItem.rightBarButtonItems?.insert(newElement: xxxButton, at:SOME_INDEX)

Hope helpful.

Coryden answered 28/2, 2017 at 13:20 Comment(0)
C
0

Set the the title to empty first and after swlwction just set again.

Conroy answered 27/10, 2018 at 19:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.