【问题标题】:How do I show/hide a UIBarButtonItem?如何显示/隐藏 UIBarButtonItem?
【发布时间】:2012-04-18 18:55:23
【问题描述】:

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

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

【问题讨论】:

  • 我只是禁用了它并添加了一个可访问性标签,说明该按钮的功能不可用。

标签: ios uibarbuttonitem uitoolbar


【解决方案1】:

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

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

【讨论】:

  • 为了使我在导航控制器中的右键可以使用 self.navigationItem.rightBarButtonItems 和 [self.navigationItem setRightBarButtonItems] 而不是 toolBarItems 和 setToolBarItems。
  • @MindSpiker:是的,他同样的技术也适用于导航栏上的按钮。
  • 我必须在 dealloc 中将 myButton 设为 nil 吗?
【解决方案2】:

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

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

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

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

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

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

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

【讨论】:

  • [self.navigationItem.rightBarButtonItem setEnabled:NO]; [self.navigationItem.rightBarButtonItem setTintColor: [UIColor clearColor]];
  • 对于 Swift:deleteButton.enabled = false; deleteButton.tintColor = UIColor.clearColor() 禁用和隐藏,deleteButton.enabled = true; deleteButton.tintColor = nil 重新启用并正常显示。
  • 我喜欢这种方法让我可以将是否在该类中显示 UIBarButton 的逻辑。它只适用于一个按钮的原因并不是很明显——这是因为如果你以这种方式隐藏一个按钮,它仍然会占用空间,所以如果你有多个按钮,你可能会有一个空白。
  • 你的第一种方法对我来说是完美的。我将UIColor.clear 设置为UIControlState.disabled,并且可以使用setEnabled 显示/隐藏按钮。当然,正如您所说,这仅适用于文本按钮。
  • 如果我长按它直到它弹出一个大图像(可能是为了便于访问)然后即使将 isEnabled 设置为 false 它仍然有效。
【解决方案3】:

这是一个简单的方法:

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 小到不会出现。

【讨论】:

  • 在所有解决方案中,这个解决方案快速、肮脏且有效。我还添加了 barbuttItem.enabled = NO;因为如果我按得足够多,我仍然可以让按钮触发。
  • 对我不起作用。我认为这是因为我使用的是带有“+”图像的添加按钮,但我尝试了一个带有文本“新建”的自定义按钮,但它仍然没有消失。启用更改,所以我知道我的代码正在执行。有任何想法吗?请注意,这个按钮是在情节提要中创建的,并且有一个 segue,所以我不想改为编程按钮
  • 它在导航控制器工具栏中似乎不起作用,但对其他工具栏却有效。
  • 它隐藏了它,但它仍然响应点击。对我来说,它就像一个隐形按钮。
  • 如果你在appdelegate中使用self.window?.tintColor = APP_PRIMARY_COLOR这一行设置了全局色调颜色,那么这将不起作用
【解决方案4】:

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

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

【讨论】:

  • 这对我有用,只需设置 btn.title = nil。我还设置了 enabled = NO,以防万一...
  • 在 iOS7 中将 buttonItem.title 设置为 nil 对我不起作用。重新设置时该按钮未重新出现。但是起作用的是设置 buttonItem.title=@" ";
【解决方案5】:

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

navBar.topItem.rightBarButtonItem = nil;

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

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

【讨论】:

  • 如果您想稍后再次设置rightBarButtonItem,请确保按钮项目存储在strong IBOutlet 中,以便在您将其从导航栏上取下时不会释放.
【解决方案6】:

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

【讨论】:

  • 但这仍然会为这个按钮占用空间。
【解决方案7】:

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

  • UINavigationItemUIBarButtonItems创建出口
  • 运行以下代码删除

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

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

【讨论】:

  • 谢谢,这也是我找到的最好的方法。只需确保您对按钮的引用是强有力的。
  • 另外,请记住,这仅在您只有一个按钮时才有效。该示例将删除该侧的所有按钮。
  • @jyoung 这对我有用,但是如果引用是强的,为什么这很重要?我没有尝试其他方式,但通常不会这样设置,因为它不是默认设置。
  • @Robert 您想在以后使用该对象,因此您需要确保当您将其设置为 nil 时该对象不会被垃圾回收。如果当您告诉条形按钮项可以删除它时没有其他东西保留该对象,则它的引用计数将为 0,并且将被垃圾回收。
【解决方案8】:

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

@IBOutlet weak var addBarButton: UIBarButtonItem!

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

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

Swift 3 中,enable 使用 isEnable 属性。

【讨论】:

    【解决方案9】:

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

    【讨论】:

      【解决方案10】:

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

      【讨论】:

        【解决方案11】:

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

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

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

        【讨论】:

          【解决方案12】:

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

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

          【讨论】:

            【解决方案13】:
            @IBDesignable class AttributedBarButtonItem: UIBarButtonItem {
            
                var isHidden: Bool = false {
            
                    didSet {
            
                        isEnabled = !isHidden
                        tintColor = isHidden ? UIColor.clear : UIColor.black
                    }
                }
            }
            

            现在只需更改 isHidden 属性。

            【讨论】:

              【解决方案14】:

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

              【讨论】:

                【解决方案15】:

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

                【讨论】:

                • 这个答案的作用是允许所有灵活的大小调整工作。这实际上是一个超级有效的答案。可能再加上一个扩展就完美了。
                【解决方案16】:

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

                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
                

                【讨论】:

                  【解决方案17】:

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

                  【讨论】:

                  • 这其实不是真的——Max 描述的方法效果很好。
                  • nothernman - Max 实际上并不正确。他实际上并没有像大多数人定义的“隐藏”那样隐藏按钮。他只是让它不可见并禁用用户交互。该按钮仍然存在并占用空间。这取决于您要如何定义“隐藏”,我相信原始问题的精神是想要实际删除/添加它,而不仅仅是让它不可见。
                  【解决方案18】:

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

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

                  【讨论】:

                  • 不错,但您必须提供 UINavigationItem 作为参数,而不是 UIToolbar,因为他要求隐藏 UIBarButtonItem。我将您的功能修改为: func hideToolbarItem(button: UIBarButtonItem, withToolbar toolbar: UINavigationItem) { var toolbarButtons: [UIBarButtonItem] = toolbar.rightBarButtonItems! toolbarButtons.removeAtIndex(toolbarButtons.indexOf(button)!) toolbar.setRightBarButtonItems(toolbarButtons, animated: true) } 效果很好
                  【解决方案19】:

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

                  例如:

                  1.有一个UIButton,您想隐藏/取消隐藏它。

                  2.UIButton 设为自定义视图。喜欢:

                  UIButton*myButton=[UIButton buttonWithType:UIButtonTypeRoundedRect];//your button
                  
                  UIBarButtonItem*yourBarButton=[[UIBarButtonItem alloc] initWithCustomView:myButton];
                  

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

                  【讨论】:

                  • 但是,它不会缩小其他按钮之间的差距:当它“隐藏”时,工具栏上会有一个空白区域。
                  • @lnafziger 是的,确实如此,但我没有阅读 OP 关于缩小按钮之间间隙的提及,但这是一个值得注意的点。
                  • 谢谢,您的回答也很有用,但我认为大多数人想要隐藏工具栏上的按钮时希望它看起来根本不存在(没有空白区域) .不过,如果是左边还是右边,这并不重要。
                  • 好点,iNoob 和 Inafziger - 我没有提到它,但是是的,我希望没有空白。
                  【解决方案20】:

                  对于 Swift 版本,代码如下:

                  对于UINavigationBar

                  self.navigationItem.rightBarButtonItem = nil
                  
                  self.navigationItem.leftBarButtonItem = nil
                  

                  【讨论】:

                    【解决方案21】:

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

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

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

                    self.navigationItem.rightBarButton.enabled = NO;
                    

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

                    【讨论】:

                    • 我在 rightBarButtonItem 中有一个按钮。所以我将其启用设置为 NO 并将其禁用状态下的图像更改为 nil。像魅力一样工作......谢谢
                    • 好主意,但是将图像设置为 null 对我不起作用,我不得不放一个 20x20 的透明小方块作为图像
                    【解决方案22】:

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

                    【讨论】:

                      【解决方案23】:

                      我认为我会根据 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];
                          }
                      }
                      

                      【讨论】:

                        【解决方案24】:

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

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

                        【讨论】:

                          【解决方案25】:

                          如果您使用的是 Swift 3

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

                          【讨论】:

                            【解决方案26】:

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

                            【讨论】:

                              【解决方案27】:

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

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

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

                              【讨论】:

                                【解决方案28】:

                                你需要操作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;
                                

                                【讨论】:

                                  【解决方案29】:

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

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

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

                                  【讨论】:

                                    【解决方案30】:

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

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

                                    【讨论】:

                                      猜你喜欢
                                      • 2011-12-12
                                      • 1970-01-01
                                      • 2012-03-24
                                      • 2012-01-23
                                      • 1970-01-01
                                      • 2016-07-21
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 2017-05-01
                                      相关资源
                                      最近更新 更多