如何在导航栏中隐藏/显示右侧按钮

50

我需要隐藏导航栏中的右侧按钮,然后在用户选择某些选项后再显示它。

不幸的是,下面的代码无效:

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

有没有办法?

18个回答

80

将引用设置为nil来隐藏按钮,但是如果以后想要恢复它,您需要保留它的副本以便重新分配。

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

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

个人而言,我会将我的导航按钮制作成 @properties,在需要时可以随意删除并重新创建,示例如下:

//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;

你的属性方法似乎是正确的解决方案。谢谢。问题:我不清楚如何调用以下方法:- (UIBarButtonItem *)rightNavButton { - Lauren Quantrell
抱歉,还有一个问题。除了使用您概述的两种方法之外,我是否可以在将按钮设置为nil后再次创建它? - Lauren Quantrell
rightNavButton函数是属性的“getter”部分,我在这里手动声明了它(“setter”由synthesize处理)。您可以通过调用self.rightNavButton来调用它。 - Matt J
你不必使用我在这里使用的结构,但我更喜欢它。习惯上,我会将任何需要在控制器逻辑中至少引用两次的内容创建为属性。这使我能够在需要时(但不是在必要之前)在一个地方进行延迟加载对象。此外,如果这是一个相当大的UIImage或声音剪辑,并且我遇到低内存情况,我可以设置self.rightNavButton = nil来释放内存,然后对象将在下一次请求时重新生成。 - Matt J

19

对于 Swift 3

if let button = self.navigationItem.rightBarButtonItem {
                    button.isEnabled = false
                    button.tintColor = UIColor.clear
                }`

11

将引用设置为nil:

current_controller_in_navcontroller.navigationItem.rightBarButtonItem =  nil;

请确保在当前由navController显示的控制器中调用此函数,而不是在navController本身中调用。


@lauren-quantrell 如果答案正确,您应该接受它,这将帮助其他阅读此帖子的用户。 - Stefan Ticu

11

显示:

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

隐藏:

[self.navigationItem.rightBarButtonItem.customView setAlpha:0.0];
你甚至可以为其显示/隐藏添加动画效果。
[UIView animateWithDuration:0.2 animations:^{
        [self.navigationItem.rightBarButtonItem.customView setAlpha:1.0];

    }];

你的解决方案太完美了 :D - Nguyễn Quang Tuấn

7
如果您只有一个在右侧的导航栏按钮,您可以使用以下代码行来处理:

self.navigationItem.rightBarButtonItem = nil;

如果您在右侧有多个导航栏按钮,例如,如果您在导航栏右侧有两个按钮(搜索按钮和筛选按钮)。此时,右侧导航栏的按钮是

self.navigationItem.rightBarButtonItems = [searchItem,filterItem]

如果您只想隐藏搜索按钮,可以使用以下代码行:

self.navigationItem.rightBarButtonItems = [filterItem]

这样,您就可以完全隐藏导航栏中的搜索按钮,并将筛选按钮放置在搜索按钮的位置。

5

这是Matt的解决方案,更新了故事板和ARC。记住,IBOutlets默认为__weak,所以您需要将其更改为strong,以避免过早释放。

@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

4

这个答案的功劳要归功于 learner,该答案来源于以下问题:

在iOS-7中按需隐藏和显示左导航栏按钮

这是一个更简单的答案。

//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];
}

然后你只需要在需要的地方引用该方法,比如在 (IBAction) 中,就像这样:

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

我尝试了所有其他方法,都没有成功,即使将我的按钮引用为@property (...) UIBarButtonItem.... ,也没有用,直到我发现这个方法。


4

SWIFT 2.2

在 Swift 2.2 中,self.navigationItem 不起作用。相反,创建一个 NavigationItem 的输出口(我在下面命名为“nav”),并使用它。

此外,在 Xcode 7.3 和 Swift 2.2 中,以下建议对我无效:

 nav.leftBarButtonItem?.customView?.hidden = true

所以我按照上面@Matt J的想法进行了操作(我左边有2个项目):

  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
    }
    

它可以工作,但似乎你不需要这个插座。 - lenooh

4

显示:

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

隐藏:

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

不起作用... - Saad Rehman
@SaadRehman 抱歉,我甚至不记得我是在哪个项目中使用这种技术的:( 我更喜欢Swift而不是Objective C。如果您愿意,在GitHub上分享一个示例,我们可以一起尝试一些东西,我很乐意提供帮助。 - Amr Angry
1
谢谢,我最终将按钮设为 nil 来隐藏它,所以没问题 :) - Saad Rehman

3

我的解决方案:

self.navigationItem.rightBarButtonItem.customView.hidden=NO;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接