我如何显示/隐藏一个UIBarButtonItem?

我在IB中创建了一个带有几个按钮的工具栏。我想能够隐藏/显示一个按钮取决于数据的状态在主窗口。

UIBarButtonItem没有隐藏属性,到目前为止我发现的任何隐藏它们的例子都涉及将导航栏按钮设置为nil,我认为我不想在这里这样做,因为我可能需要再次显示按钮(更不用说,如果我将按钮连接到IBOutlet,如果我将其设置为nil,我不确定如何取回它)。

159588 次浏览

没有办法“隐藏”一个UIBarButtonItem,你必须从superView中删除它,当你想再次显示它时再添加它。

您需要操作工具栏。条目数组。

下面是我用来隐藏和显示Done按钮的一些代码。如果你的按钮在工具栏的极端边缘或在其他按钮之间,你的其他按钮将移动,所以如果你想让你的按钮只是消失,然后把你的按钮作为最后一个按钮的中心。我动画按钮移动的效果,我很喜欢它。

-(void)initLibraryToolbar {


libraryToolbarDocumentManagementEnabled = [NSMutableArray   arrayWithCapacity:self.libraryToolbar.items.count];
libraryToolbarDocumentManagementDisabled = [NSMutableArray arrayWithCapacity:self.libraryToolbar.items.count];
[libraryToolbarDocumentManagementEnabled addObjectsFromArray:self.libraryToolbar.items];
[libraryToolbarDocumentManagementDisabled addObjectsFromArray:self.libraryToolbar.items];
trashCan = [libraryToolbarDocumentManagementDisabled objectAtIndex:3];
mail = [libraryToolbarDocumentManagementDisabled objectAtIndex:5];
[libraryToolbarDocumentManagementDisabled removeObjectAtIndex:1];
trashCan.enabled = NO;
mail.enabled = NO;
[self.libraryToolbar setItems:libraryToolbarDocumentManagementDisabled animated:NO];

所以现在可以使用下面的代码来显示您的按钮

[self.libraryToolbar setItems:libraryToolbarDocumentManagementEnabled animated:YES];
trashCan.enabled = YES;
mail.enabled = YES;

或者隐藏你的纽扣

[self.libraryToolbar setItems:libraryToolbarDocumentManagementDisabled animated:YES];
trashCan.enabled = NO;
mail.enabled = NO;

将按钮保存在<强大的>强大的 outlet中(让我们称其为myButton),并执行以下操作来添加/删除它:

// Get the reference to the current toolbar buttons
NSMutableArray *toolbarButtons = [self.toolbarItems mutableCopy];


// This is how you remove the button from the toolbar and animate it
[toolbarButtons removeObject:self.myButton];
[self setToolbarItems:toolbarButtons animated:YES];


// This is how you add the button to the toolbar and animate it
if (![toolbarButtons containsObject:self.myButton]) {
// The following line adds the object to the end of the array.
// If you want to add the button somewhere else, use the `insertObject:atIndex:`
// method instead of the `addObject` method.
[toolbarButtons addObject:self.myButton];
[self setToolbarItems:toolbarButtons animated:YES];
}

因为它存储在输出中,所以即使它不在工具栏上,您也将保留对它的引用。

一种方法是在分配UIBarButtonItem时使用的initWithCustomView:(UIView *)属性。UIView的子类将具有hide/unhide属性。

例如:

1.有一个你想隐藏/取消隐藏的UIButton

将__abc0设置为自定义视图。如:

UIButton*myButton=[UIButton buttonWithType:UIButtonTypeRoundedRect];//your button


UIBarButtonItem*yourBarButton=[[UIBarButtonItem alloc] initWithCustomView:myButton];

你可以隐藏/取消隐藏你创建的myButton[myButton setHidden:YES];

我的解决方案是设置bounds.width到0,你有什么UIBarButtonItem(我使用这种方法与UIButton和UISearchBar):

隐藏:

self.btnXXX.bounds = CGRectMake(0,0,0,0);

显示:

self.btnXXX.bounds = CGRectMake(0,0,40,30); // <-- put your sizes here

这里有一个简单的方法:

hide:  barbuttonItem.width = 0.01;
show:  barbuttonItem.width = 0; //(0 defaults to normal button width, which is the width of the text)

我刚刚在retina iPad上运行了它,0.01太小了,它不会显示出来。

self.dismissButton.customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];

在IB中,如果你让按钮的标题为空,它将不会出现(从未初始化?)我经常在UI更新的开发过程中这样做,如果我想让一个栏按钮项目临时消失,而不删除它并丢弃它的所有出口引用。

这在运行时没有相同的效果,将按钮的标题设置为nil不会导致整个按钮消失。抱歉并不能真正回答你的问题,但可能对一些人有用。

编辑:此技巧仅在按钮的样式设置为普通时有效

可以在不改变其宽度或将其从工具条中移除的情况下将按钮隐藏在适当的位置。如果将样式设置为普通,删除标题并禁用按钮,则该按钮将消失。要恢复它,只需反转您的更改。

-(void)toggleBarButton:(bool)show
{
if (show) {
btn.style = UIBarButtonItemStyleBordered;
btn.enabled = true;
btn.title = @"MyTitle";
} else {
btn.style = UIBarButtonItemStylePlain;
btn.enabled = false;
btn.title = nil;
}
}

补充Eli Burke的回答,如果你的__abc0有一个背景图像而不是一个标题,你可以使用以下代码:

-(void)toggleLogoutButton:(bool)show{
if (show) {
self.tabButton.style = UIBarButtonItemStyleBordered;
self.tabButton.enabled = true;
UIImage* imageMap = [UIImage imageNamed:@"btn_img.png"];
[((UIButton *)[self.tabButton customView]) setBackgroundImage:imageMap forState:UIControlStateNormal];
} else {
self.tabButton.style = UIBarButtonItemStylePlain;
self.tabButton.enabled = false;
[((UIButton *)[self.tabButton customView]) setBackgroundImage:nil forState:UIControlStateNormal];
}
}

下面是我的解决方案,虽然我正在寻找它的导航栏。

navBar.topItem.rightBarButtonItem = nil;
这里“navBar”是XIB视图中NavigationBar的IBOutlet 在这里,我想隐藏按钮或根据某些条件显示它。所以我在测试“如果”的条件,如果为真,我将在目标视图的viewDidLoad方法中将按钮设置为nil

这可能与你的问题不相关,但如果你想隐藏导航栏上的按钮,情况类似

我将在这里添加我的解决方案,因为我还没有在这里找到它。我有一个动态按钮,其图像取决于一个控件的状态。对我来说最简单的解决方案是,如果控件不存在,将图像设置为nil。每次控件更新时,图像都会更新,因此,这对我来说是最优的。只是为了确保我还将enabled设置为NO

将宽度设置为最小值在iOS 7上不起作用。

归功于@lnafziger, @MindSpiker, @vishal等人,

我为单个右(或左)栏按钮设计的最简单的一行代码是:

self.navigationItem.rightBarButtonItem = <#StateExpression#>
? <#StrongPropertyButton#> : nil;

如:

@interface MyClass()


@property (strong, nonatomic) IBOutlet UIBarButtonItem *<#StrongPropertyButton#>;


@end


@implementation


- (void) updateState
{
self.navigationItem.rightBarButtonItem = <#StateExpression#>
? <#StrongPropertyButton#> : nil;
}


@end

我测试了这个,它为我工作(与强栏按钮项目有线通过IB)。

当栏按钮项被禁用时,将文本颜色设置为透明颜色可能是一个更干净的选项。你不需要在评论中解释什么奇怪的事情。此外,您不会破坏按钮,因此您仍然保留任何相关的故事板segue。

[self.navigationItem.rightBarButtonItem setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor clearColor]}
forState:UIControlStateDisabled];

然后当你想隐藏栏按钮项时,你可以这样做:

self.navigationItem.rightBarButton.enabled = NO;

虽然没有隐藏属性,但结果是一样的。

如果UIBarButtonItem有一个图像而不是文本,你可以这样做来隐藏它: navigationBar.topItem.rightBarButtonItem.customView.alpha = 0.0; < / p >

我知道这个回答有点晚了。然而,如果其他人面临类似的情况,这可能会有所帮助。

在iOS 7中,要隐藏栏按钮项,我们可以使用以下两种技术:-

  • 使用SetTitleTextAttributes:-这适用于栏按钮项目,如“完成”,“保存”等。然而,它不工作的项目,如添加,垃圾符号等(至少不是为我),因为他们不是文本。
  • 如果我有一个名为“deleteButton”的栏按钮项:-

为了隐藏按钮,我使用以下代码:-

[self.deleteButton setEnabled:NO];
[self.deleteButton setTintColor: [UIColor clearColor]];

要再次显示按钮,我使用以下代码

[self.deleteButton setEnabled:YES];
[self.deleteButton setTintColor:nil];
UIBarButtonItem < p >子类。 确保Interface Builder中的按钮设置为HidableBarButtonItem。 创建一个从按钮到视图控制器的outlet。在视图控制器中,你可以通过调用setHidden:

来隐藏/显示按钮

HidableBarButtonItem.h

#import <UIKit/UIKit.h>


@interface HidableBarButtonItem : UIBarButtonItem


@property (nonatomic) BOOL hidden;


@end

HidableBarButtonItem.m

#import "HidableBarButtonItem.h"


@implementation HidableBarButtonItem


- (void)setHidden:(BOOL const)hidden {
_hidden = hidden;


self.enabled = hidden ? YES : NO;
self.tintColor = hidden ? [UIApplication sharedApplication].keyWindow.tintColor : [UIColor clearColor];
}


@end

我目前正在运行OS X Yosemite开发者预览7和Xcode 6 beta 6,目标是iOS 7.1,以下解决方案对我来说很好:

  • 为__abc0和UIBarButtonItems创建outlet
  • 运行以下代码删除

    [self.navItem setRightBarButtonItem:nil];
    [self.navItem setLeftBarButtonItem:nil];
    
  • Run following codes to add buttons again

    [self.navItem setRightBarButtonItem:deleteItem];
    [self.navItem setLeftBarButtonItem:addItem];
    

我使用xib和UIToolbar。BarButtonItem在xib文件中创建。我为BarButtonItem创建了IBOutlet。我用这段代码来隐藏BarButtonItem

 self.myBarButtonItem.enabled = NO;
self.myBarButtonItem.title =  nil;

这对我很有帮助。

尝试在斯威夫特,不要更新tintColor如果你有一些设计你的UIBarButtonItem字体大小在AppDelegate,它将完全改变你的按钮的外观时显示。

在文本按钮的情况下,改变标题可以让你的按钮“消失”。

if WANT_TO_SHOW {
myBarButtonItem.enabled = true
myBarButtonItem.title = "BUTTON_NAME"
}else{
myBarButtonItem.enabled = false
myBarButtonItem.title = ""
}
< p > iOS 8。带有自定义图像的UIBarButtonItem。 我试过很多方法,但大多数都没用。 在Max的解决方案中,__abc0没有改变任何颜色。 这是我自己想出来的,我想它会对别人有用

隐藏:

[self.navigationItem.rightBarButtonItem setEnabled:NO];
[self.navigationItem.rightBarButtonItem setImage:nil];

显示:

[self.navigationItem.rightBarButtonItem setEnabled:YES];
[self.navigationItem.rightBarButtonItem setImage:image];

你可以使用文本属性隐藏工具栏按钮:

barButton.enabled = false
barButton.setTitleTextAttributes([NSForegroundColorAttributeName : UIColor.clearColor()], forState: .Normal)

也看到我的解决方案与UIBarButtonItem扩展类似的问题:使用快速IOS使UIBarButtonItem消失

我认为我将根据lnafziger接受的答案分享一些帮助方法,因为我在每个工具栏中都有多个按钮:

-(void) hideToolbarItem:(UIBarButtonItem*) button inToolbar:(UIToolbar*) toolbar{
NSMutableArray *toolbarButtons = [toolbar.items mutableCopy];
[toolbarButtons removeObject:button];
[toolbar setItems:toolbarButtons animated:NO];
}


-(void) showToolbarItem:(UIBarButtonItem*) button inToolbar:(UIToolbar*) toolbar atIndex:(int) index{
NSMutableArray *toolbarButtons = [toolbar.items mutableCopy];
if (![toolbarButtons containsObject:button]){
[toolbarButtons insertObject:button atIndex:index];
[self setToolbarItems:toolbarButtons animated:YES];
}
}

来自@lnafziger的回答

将你的Barbuttons保存在强劲的出口中,并隐藏/显示它:

-(void) hideBarButtonItem :(UIBarButtonItem *)myButton {
// Get the reference to the current toolbar buttons
NSMutableArray *navBarBtns = [self.navigationItem.rightBarButtonItems mutableCopy];


// This is how you remove the button from the toolbar and animate it
[navBarBtns removeObject:myButton];
[self.navigationItem setRightBarButtonItems:navBarBtns animated:YES];
}




-(void) showBarButtonItem :(UIBarButtonItem *)myButton {
// Get the reference to the current toolbar buttons
NSMutableArray *navBarBtns = [self.navigationItem.rightBarButtonItems mutableCopy];


// This is how you add the button to the toolbar and animate it
if (![navBarBtns containsObject:myButton]) {
[navBarBtns addObject:myButton];
[self.navigationItem setRightBarButtonItems:navBarBtns animated:YES];
}
}

当需要使用以下功能..

[self showBarButtonItem:self.rightBarBtn1];
[self hideBarButtonItem:self.rightBarBtn1];

对于Swift版本,下面是代码:

UINavigationBar:

self.navigationItem.rightBarButtonItem = nil


self.navigationItem.leftBarButtonItem = nil

这是一个很长的答案列表,但为了防止有人想要一个简单的复制和粘贴的快速解决方案,这里是

func hideToolbarItem(button: UIBarButtonItem, withToolbar toolbar: UIToolbar) {
var toolbarButtons: [UIBarButtonItem] = toolbar.items!
toolbarButtons.removeAtIndex(toolbarButtons.indexOf(button)!)
toolbar.setItems(toolbarButtons, animated: true)
}


func showToolbarItem(button: UIBarButtonItem, inToolbar toolbar: UIToolbar, atIndex index: Int) {
var toolbarButtons: [UIBarButtonItem] = toolbar.items!
if !toolbarButtons.contains(button) {
toolbarButtons.insert(button, atIndex: index)
toolbar.setItems(toolbarButtons, animated:true);
}
}

您可以很容易地获得视图并隐藏它

let view: UIView = barButtonItem.valueForKey("view") as! UIView
view.hidden = true

我在我的项目中使用了IBOutlets。所以我的解决方案是:

@IBOutlet weak var addBarButton: UIBarButtonItem!


addBarButton.enabled = false
addBarButton.tintColor = UIColor.clearColor()

当您需要再次显示此栏时,只需设置反转属性。

斯威夫特3中,改用enable使用isEnable属性。

如果你使用的是Swift 3

if (ShowCondition){
self.navigationItem.rightBarButtonItem = self.addAsset_btn
}
else {
self.navigationItem.rightBarButtonItem = nil
}

对于Swift 3和Swift 4,你可以这样做来隐藏UIBarButtomItem:

self.deleteButton.isEnabled = false
self.deleteButton.tintColor = UIColor.clear

并显示UIBarButtonItem:

self.deleteButton.isEnabled = true
self.deleteButton.tintColor = UIColor.blue

tintColor上,必须指定用于UIBarButtomItem的原始颜色

@IBDesignable class AttributedBarButtonItem: UIBarButtonItem {


var isHidden: Bool = false {


didSet {


isEnabled = !isHidden
tintColor = isHidden ? UIColor.clear : UIColor.black
}
}
}

现在只需更改isHidden属性。

只要设置barButton.customView = UIView(),就可以看到窍门了

我在Max和其他人建议的tintColorisEnabled方法中发现了另一个问题-当VoiceOver为可访问性启用并且按钮是在逻辑上隐藏时,可访问性光标仍然会集中在栏按钮上,并声明它是“暗”的(即因为isEnabled被设置为false)。接受的答案中的方法不会受到这种副作用的影响,但我发现的另一种方法是在“隐藏”按钮时将isAccessibilityElement设置为false:

deleteButton.tintColor = UIColor.clear
deleteButton.isEnabled = false
deleteButton.isAccessibilityElement = false

然后在“显示”按钮时将isAccessibilityElement设置为true:

deleteButton.tintColor = UIColor.blue
deleteButton.isEnabled = true
deleteButton.isAccessibilityElement = true

在我的例子中,栏按钮项仍然占据空间不是问题,因为我们隐藏/显示了右栏按钮项的最左侧。

这是一个扩展,将处理这一点。

extension UIBarButtonItem {


var isHidden: Bool {
get {
return tintColor == .clear
}
set {
tintColor = newValue ? .clear : .white //or whatever color you want
isEnabled = !newValue
isAccessibilityElement = !newValue
}
}


}

用法:

myBarButtonItem.isHidden = true

我的答案是斯威夫特!

if $0 {
self.navigationItem.rightBarButtonItems = [UIBarButtonItem(customView: self.button1)]
} else {
self.navigationItem.rightBarButtonItems = [UIBarButtonItem(customView: self.button2)]
}

为了隐藏许多项目之一,我使用以下代码:

self.navigationItem.leftBarButtonItems?.remove(at: 0)
self.navigationItem.rightBarButtonItems?.remove(at: 1)

我想如果需要的话可以重新添加。

我有一个问题,我有2 leftBarButtonItems。在Mac Catalyst上,firstButton指向一个不支持的操作:用AVFoundation录制视频。Mac Catalyst上只有第二个按钮有效:使用UIImagePickerController。

所以在Mac Catalyst上,我必须将第一个UIBarButtonItem指向secondButton,并始终隐藏第二个UIBarButtonItem。在iOS上,两个按钮都应该显示出来。这就是我的解决方案:

#if TARGET_OS_MACCATALYST
self.navigationItem.leftBarButtonItem = self.secondButton;
NSUInteger count = [self.navigationItem.leftBarButtonItems count];
for (NSUInteger i = 0; i < count; i++) {
UIBarButtonItem *thisButton = [self.navigationItem.leftBarButtonItems objectAtIndex:i];
if (i == 1) {
thisButton.enabled = NO;
thisButton.tintColor = [UIColor clearColor];
}
}
#else
self.navigationItem.leftBarButtonItem = self.firstButton;
#endif

我希望它能帮助到有类似问题的人。

最后,在iOS 16 +中,UIBarButtonItem具有isHidden属性。

所以,扩展现有的答案,比如

extension UIBarButtonItem {
func show() {
if #available(iOS 16.0, *) {
isHidden = false
} else {
isEnabled = true
tintColor = .white
}
}
    

func hide() {
if #available(iOS 16.0, *) {
isHidden = true
} else {
isEnabled = false
tintColor = .clear
}
}
}