ChatGPT解决这个技术问题 Extra ChatGPT

如何显示/隐藏 UIBarButtonItem?

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

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

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

l
lnafziger

将您的按钮保存在 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 吗?
M
Max

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

在 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 的逻辑。它只适用于一个按钮的原因并不是很明显——这是因为如果你以这种方式隐藏一个按钮,它仍然会占用空间,所以如果你有多个按钮,你可能会有一个空白。
你的第一种方法对我来说是完美的。我为 UIControlState.disabled 设置了 UIColor.clear,并且可以使用 setEnabled 显示/隐藏按钮。当然,正如您所说,这仅适用于文本按钮。
如果我长按它直到它以大图像弹出(可能是为了便于访问),那么即使将 isEnabled 设置为 false 它仍然有效。
k
kbpontius

这是一个简单的方法:

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 设置了全局色调颜色,那么这将不起作用
E
Eli Burke

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

-(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,这对我有用。我也设置启用=否,以防万一......
在 iOS7 中将 buttonItem.title 设置为 nil 对我不起作用。重新设置时该按钮未重新出现。然而起作用的是设置 buttonItem.title=@" ";
v
vishal dharankar

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

navBar.topItem.rightBarButtonItem = nil;

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

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


如果您想稍后再次设置 rightBarButtonItem,请确保按钮项目存储在 strong IBOutlet 中,以便在您将其从导航栏上取下时不会释放它。
p
pableiros

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


但这仍然会为此按钮占用空间。
O
Olcay Ertaş

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

为 UINavigationItem 和 UIBarButtonItems 创建 outlet

运行以下代码删除 [self.navItem setRightBarButtonItem:nil]; [self.navItem setLeftBarButtonItem:nil];

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


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

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

@IBOutlet weak var addBarButton: UIBarButtonItem!

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

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

Swift 3 中,enable 使用 isEnable 属性。


V
Vyacheslav

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


R
Rinto Rapheal

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

J
Jeffrey Neo

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

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

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

E
Evan Kirkwood

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

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


E
Elijah

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

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

B
Bartłomiej Semańczyk
@IBDesignable class AttributedBarButtonItem: UIBarButtonItem {

    var isHidden: Bool = false {

        didSet {

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

现在只需更改 isHidden 属性。


d
delavega66

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

A
Anton

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


这个答案的作用是让所有灵活的大小都起作用。这实际上是一个超级有效的答案。可能再加上一个扩展,这将是完美的。
K
Kyle Richter

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


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

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

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) } 效果很好
i
iNoob

一种方法是在分配 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 - 我没有提到它,但是是的,我希望没有空白点。
S
Sohil R. Memon

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

对于 UINavigationBar

self.navigationItem.rightBarButtonItem = nil

self.navigationItem.leftBarButtonItem = nil

p
puppybits

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

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

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

self.navigationItem.rightBarButton.enabled = NO;

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


我在 rightBarButtonItem 中有一个按钮。所以我将其启用设置为 NO 并将其禁用状态下的图像更改为 nil。像魅力一样工作......谢谢
好主意,但是将图像设置为 null 对我不起作用,我不得不放一个 20x20 的透明正方形作为图像
A
Artem Goryaev

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


G
Guy Lowe

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

T
Titouan de Bailleul

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

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

M
Museer Ahamad Ansari

如果您使用的是 Swift 3

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

R
Renato Lochetti

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

C
Community

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

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

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


G
Graham

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

p
pretzels1337

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

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

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


m
mkko

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

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


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅