如何显示/隐藏UIBarButtonItem?

时间:2012-04-05 02:04:29

标签: ios uibarbuttonitem uitoolbar

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

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

37 个答案:

答案 0 :(得分:254)

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

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

答案 1 :(得分:201)

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

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

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

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

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

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

[self.deleteButton setEnabled:YES];
[self.deleteButton setTintColor:nil];

答案 2 :(得分:66)

这是一个简单的方法:

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

我只是在我的视网膜iPad上运行它,而.01足够小,不会出现。

答案 3 :(得分:57)

可以在不改变宽度或将其从条形图中移除的情况下隐藏按钮。如果将样式设置为plain,删除标题,并禁用该按钮,它将消失。要恢复它,只需撤消更改即可。

-(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;
    }
}

答案 4 :(得分:42)

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

navBar.topItem.rightBarButtonItem = nil;

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

这可能与您的问题无关,但如果您想要隐藏NavigationBar上的按钮,则会出现类似情况

答案 5 :(得分:24)

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

的原点颜色

答案 6 :(得分:22)

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

  • UINavigationItemUIBarButtonItem s
  • 创建插座
  • 运行以下代码以删除

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

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

答案 7 :(得分:14)

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

@IBOutlet weak var addBarButton: UIBarButtonItem!

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

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

Swift 3 而不是enable使用isEnable属性。

答案 8 :(得分: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];

答案 9 :(得分:12)

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

答案 10 :(得分:9)

尝试使用 Swift ,如果你的UIBarButtonItem有一些像AppDelegate中字体大小的设计,请不要更新tintColor,它会在你出现时完全改变按钮的外观

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

if WANT_TO_SHOW {
    myBarButtonItem.enabled = true
    myBarButtonItem.title = "BUTTON_NAME"
}else{
    myBarButtonItem.enabled = false
    myBarButtonItem.title = ""
}

答案 11 :(得分:6)

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

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

答案 12 :(得分:6)

@IBDesignable class AttributedBarButtonItem: UIBarButtonItem {

    var isHidden: Bool = false {

        didSet {

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

现在只需更改isHidden属性。

答案 13 :(得分:5)

改进@lnafziger回答

将您的Barbutton保存在强力出口中并执行此操作以隐藏/显示它:

-(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];

答案 14 :(得分: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);
    }
}

答案 15 :(得分:4)

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

答案 16 :(得分: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];

答案 17 :(得分:2)

您可以轻松获取视图并以此方式隐藏

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

答案 18 :(得分: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];
    }
}

答案 19 :(得分:2)

如果您使用的是Swift 3

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

答案 20 :(得分:2)

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

答案 21 :(得分:2)

禁用条形按钮项目时,将文本颜色设置为清晰颜色可能是一个更干净的选项。你必须在评论中解释这些并不奇怪。此外,您不会销毁该按钮,因此您仍然可以保留任何相关的故事板。

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

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

self.navigationItem.rightBarButton.enabled = NO;

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

答案 22 :(得分:2)

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

即可

答案 23 :(得分:1)

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

UINavigationBar

self.navigationItem.rightBarButtonItem = nil

self.navigationItem.leftBarButtonItem = nil

答案 24 :(得分: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];
    }
}

答案 25 :(得分:1)

这是将处理此问题的扩展。

torchtext

用法:

extension UIBarButtonItem {

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

}

答案 26 :(得分:0)

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

 self.myBarButtonItem.enabled = NO;
 self.myBarButtonItem.title =  nil;
这对我有所帮助。

答案 27 :(得分:0)

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

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

我想这些物品可以根据需要重新添加。

答案 28 :(得分: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

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

答案 29 :(得分:0)

您可以使用文本属性隐藏栏按钮:

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

另请参阅我的解决方案,其中包含类似问题的UIBarButtonItem扩展名:Make a UIBarButtonItem disapear using swift IOS

答案 30 :(得分: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

答案 31 :(得分: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连接强力条形按钮项目)。

答案 32 :(得分:0)

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

将宽度设置为最小值在iOS 7上无效。

答案 33 :(得分:0)

在IB中,如果您将按钮的标题留空,它将不会出现(从未初始化?)。我在UI更新期间经常在开发期间执行此操作,如果我想要一个条形按钮项目临时消失,而不删除它并删除其所有插座引用。

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

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

时有效

答案 34 :(得分: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;

答案 35 :(得分:-1)

我的答案是关于Swift 4的!

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

答案 36 :(得分:-5)

我的解决方案是将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