如何显示/隐藏UIBarButtonItem?

问题描述 投票:239回答:36

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

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

ios uibarbuttonitem uitoolbar
36个回答
256
投票

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

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


12
投票

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


9
投票

尝试使用Swift,如果您在AppDelegate中有类似于UIBarButtonItem的设计,请不要更新tintColor,它会在显示时完全改变按钮的外观。

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

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

6
投票
@IBDesignable class AttributedBarButtonItem: UIBarButtonItem {

    var isHidden: Bool = false {

        didSet {

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

现在只需更改isHidden属性。


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

由于我们隐藏/显示最左侧的条形按钮项目,因此条形按钮项目仍占用空间不是问题。


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

4
投票

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


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

3
投票

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

例如:

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

2.使UIButtonas成为自定义视图。喜欢 :

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

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

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


2
投票

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

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

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

self.navigationItem.rightBarButton.enabled = NO;

这是蹩脚的,没有隐藏的财产,但这提供了相同的结果。


2
投票

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


206
投票

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

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

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

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

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

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

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

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

2
投票

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

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

2
投票

如果您使用的是Swift 3

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

2
投票

只需设置barButton.customView = UIView(),看看诡计


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

1
投票

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

对于UINavigationBar

self.navigationItem.rightBarButtonItem = nil

self.navigationItem.leftBarButtonItem = nil

1
投票

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

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

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;

0
投票

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

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

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


0
投票

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

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


67
投票

这是一个简单的方法:

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

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


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


58
投票

可以在不改变宽度或将其从条形图中移除的情况下隐藏按钮。如果将样式设置为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;
    }
}

42
投票

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

navBar.topItem.rightBarButtonItem = nil;

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

这可能与您的问题无关,但如果您想隐藏导航栏上的按钮,则可能类似


25
投票

对于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的原点颜色


22
投票

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

  • UINavigationItemand UIBarButtonItems创建出口
  • 运行以下代码以删除 [self.navItem setRightBarButtonItem:nil]; [self.navItem setLeftBarButtonItem:nil];
  • 运行以下代码以再次添加按钮 [self.navItem setRightBarButtonItem:deleteItem]; [self.navItem setLeftBarButtonItem:addItem];

14
投票

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

@IBOutlet weak var addBarButton: UIBarButtonItem!

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

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

在Swift 3中,enable使用isEnable属性。


12
投票

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

隐藏:

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

用于显示:

[self.navigationItem.rightBarButtonItem setEnabled:YES];
[self.navigationItem.rightBarButtonItem setImage:image];
© www.soinside.com 2019 - 2024. All rights reserved.