267

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

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

4

37 回答 37

270

将您的按钮保存在一个强大的插座中(我们称之为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];
}

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

于 2012-04-05T03:18:18.560 回答
224

我知道这个问题的答案已经晚了。但是,如果其他人面临类似情况,它可能会有所帮助。

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

  • 使用SetTitleTextAttributes:- 这在“完成”、“保存”等条形按钮项目上效果很好。但是,它不适用于添加、垃圾符号等项目(至少对我来说不是),因为它们不是文本。
  • 使用TintColor:- 如果我有一个名为“deleteButton”的条形按钮项:-

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

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

为了再次显示该按钮,我使用了以下代码:-

[self.deleteButton setEnabled:YES];
[self.deleteButton setTintColor:nil];
于 2014-07-09T00:48:44.723 回答
67

这是一个简单的方法:

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

我刚刚在我的 Retina iPad 上运行了它,而且 .01 小到它不会出现。

于 2012-08-25T19:31:28.697 回答
61

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

-(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;
    }
}
于 2013-05-03T17:22:43.207 回答
44

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

navBar.topItem.rightBarButtonItem = nil;

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

这可能与您的问题不完全相关,但如果您想隐藏 NavigationBar 上的按钮,则类似的情况

于 2013-09-17T11:50:22.940 回答
35

对于 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

于 2016-12-02T19:50:06.320 回答
22

我目前正在运行针对 iOS 7.1 的 OS X Yosemite Developer Preview 7 和 Xcode 6 beta 6,以下解决方案对我来说很好:

  • UINavigationItem为和UIBarButtonItems创建出口
  • 运行以下代码删除

    [self.navItem setRightBarButtonItem:nil];
    [self.navItem setLeftBarButtonItem:nil];
    
  • 运行以下代码再次添加按钮

    [self.navItem setRightBarButtonItem:deleteItem];
    [self.navItem setLeftBarButtonItem:addItem];
    
于 2014-09-23T01:53:52.050 回答
14

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

@IBOutlet weak var addBarButton: UIBarButtonItem!

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

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

Swift 3enable使用isEnable属性。

于 2016-06-19T13:58:01.990 回答
13

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

于 2012-12-12T09:02:17.817 回答
12

iOS 8. 带有自定义图像的 UIBarButtonItem。尝试了许多不同的方法,大多数都没有帮助。Max的解决方案,setTintColor没有改变任何颜色。我自己想出了这个,认为它会对某些人有用。

隐藏:

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

展示:

[self.navigationItem.rightBarButtonItem setEnabled:YES];
[self.navigationItem.rightBarButtonItem setImage:image];
于 2015-07-03T10:46:52.657 回答
9

在Swift中尝试,tintColor如果您有一些 UIBarButtonItem 设计,例如 AppDelegate 中的字体大小,请不要更新,它会在显示时完全改变您的按钮的外观。

如果是文本按钮,更改标题可以让您的按钮“消失”。

if WANT_TO_SHOW {
    myBarButtonItem.enabled = true
    myBarButtonItem.title = "BUTTON_NAME"
}else{
    myBarButtonItem.enabled = false
    myBarButtonItem.title = ""
}
于 2015-04-15T15:09:54.610 回答
9

tintColor我在 Max和其他人建议的方法中发现了另一个问题isEnabled- 当 VoiceOver 启用辅助功能并且按钮在逻辑上隐藏时,辅助功能光标仍将聚焦在条形按钮上,并声明它“变暗”(即isEnabled因为设置为假)。接受的答案中的方法不会受到这种副作用的影响,但我发现的另一个解决方法是isAccessibilityElement在“隐藏”按钮时设置为 false:

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

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

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

在我的情况下,让条形按钮项仍然占用空间不是问题,因为我们隐藏/显示了最左侧的右侧条形按钮项。

于 2017-12-19T23:00:53.453 回答
6
@IBDesignable class AttributedBarButtonItem: UIBarButtonItem {

    var isHidden: Bool = false {

        didSet {

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

现在只需更改isHidden属性。

于 2017-05-10T11:26:50.280 回答
5

从@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];
于 2015-11-20T11:16:49.267 回答
5

只需设置 barButton.customView = UIView()并查看技巧

于 2017-08-04T07:40:35.760 回答
5

这是一个可以处理这个问题的扩展。

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
于 2018-07-08T00:09:23.147 回答
4

没有办法“隐藏” UIBarButtonItem,您必须将其从 superView 中删除,并在您想再次显示时将其添加回来。

于 2012-04-05T02:29:16.627 回答
4

这在答案列表中还有很长的路要走,但以防万一有人想要一个简单的复制和粘贴来快速解决方案,这里是

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);
    }
}
于 2016-01-30T22:20:11.997 回答
3

一种方法是 initWithCustomView:(UIView *)在分配UIBarButtonItem. 的子类UIView将具有隐藏/取消隐藏属性。

例如:

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

2.将其UIButton设为自定义视图。像 :

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

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

3.您可以隐藏/取消隐藏myButton您创建的。[myButton setHidden:YES];

于 2012-04-05T03:26:59.083 回答
3

对于 Swift 版本,这里是代码:

对于UINavigationBar

self.navigationItem.rightBarButtonItem = nil

self.navigationItem.leftBarButtonItem = nil
于 2015-12-01T09:16:46.047 回答
2

当栏按钮项被禁用时,将文本颜色设置为清晰的颜色可能是一个更干净的选项。您不必在评论中解释任何奇怪之处。此外,您不会破坏按钮,因此您仍然保留任何相关的故事板 segues。

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

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

self.navigationItem.rightBarButton.enabled = NO;

没有隐藏的属性很糟糕,但这提供了相同的结果。

于 2014-04-04T17:28:11.140 回答
2

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

于 2014-06-10T19:58:06.493 回答
2

我认为我会根据 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];
    }
}
于 2015-11-13T01:18:44.170 回答
2

您可以通过这种方式轻松获取视图并将其隐藏

let view: UIView = barButtonItem.valueForKey("view") as! UIView
view.hidden = true
于 2016-05-31T15:49:15.277 回答
2

如果您使用的是 Swift 3

if (ShowCondition){
   self.navigationItem.rightBarButtonItem = self.addAsset_btn 
 } 
else {
   self.navigationItem.rightBarButtonItem = nil
 }
于 2016-10-25T07:14:04.807 回答
1

补充 Eli Burke 的回复,如果您UIBarButtonItem有背景图片而不是标题,您可以使用以下代码:

-(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];
    }
}
于 2013-09-16T17:57:18.080 回答
1

您可以使用文本属性来隐藏条形按钮:

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

另请参阅我的 UIBarButtonItem 扩展解决方案以解决类似的问题:Make a UIBarButtonItem disapear using swift IOS

于 2015-08-21T11:43:40.243 回答
0

您需要操作 toolbar.items 数组。

这是我用来隐藏和显示完成按钮的一些代码。如果您的按钮位于工具栏的最边缘或其他按钮之间,您的其他按钮将移动,因此如果您希望按钮消失,请将您的按钮作为最后一个按钮放在中心。我为按钮移动设置动画效果,我非常喜欢它。

-(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;
于 2012-04-05T02:47:14.250 回答
0

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

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

编辑:这个技巧只有在按钮的样式设置为普通时才有效

于 2013-01-10T21:00:18.700 回答
0

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

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

于 2013-11-10T20:36:45.737 回答
0

感谢@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 连接的强大的条形按钮项目)。

于 2014-02-09T17:23:50.653 回答
0

子类UIBarButtonItem。确保 Interface Builder 中的按钮设置为HidableBarButtonItem. 制作从按钮到视图控制器的出口。然后从视图控制器中,您可以通过调用隐藏/显示按钮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
于 2014-08-28T07:44:57.060 回答
0

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

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

这对我有帮助。

于 2015-01-20T13:20:57.790 回答
0

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

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

我想如果需要可以重新添加这些项目。

于 2019-06-11T08:20:49.587 回答
0

我有 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

我希望它可以帮助有类似问题的人。

于 2020-04-25T15:45:06.367 回答
-1

我的答案是 Swift 4!

if $0 {
    self.navigationItem.rightBarButtonItems = [UIBarButtonItem(customView: self.button1)]
} else {
    self.navigationItem.rightBarButtonItems = [UIBarButtonItem(customView: self.button2)]
}
于 2019-03-21T13:56:05.387 回答
-5

bounds.width对于您在 UIBarButtonItem 中的内容,我的解决方案设置为 0(我将这种方法与 UIButton 和 UISearchBar 一起使用):

隐藏:

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

显示:

self.btnXXX.bounds = CGRectMake(0,0,40,30); // <-- put your sizes here
于 2012-05-25T03:08:21.940 回答