Как Показать / Скрыть UIBarButtonItem?

Я создал панель инструментов В IB с несколькими кнопками. Я хотел бы быть в состоянии Скрыть/показать одну из кнопок в зависимости от состояния данных в главном окне.

UIBarButtonItem не имеют скрытые свойства, и какие-либо примеры, которые я нашел до сих пор для сокрытия их включают установку навигационной панели кнопки не пропустит, что я не думаю, что я хочу сделать здесь, потому что мне может понадобиться, чтобы показать кнопку еще раз (не говоря уже о том, если подключить кнопку к IBOutlet, если я что не пропустит я не уверен как я получу его обратно).

30 ответов


сохранить закладку в сильный выход (назовем его 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];
}

поскольку он хранится в розетке, вы будете хранить ссылку на него, даже если его нет на панели инструментов.


Я знаю, что этот ответ опоздал на этот вопрос. Однако это может помочь, если кто-то еще столкнется с подобной ситуацией.

в iOS 7, чтобы скрыть элемент кнопки панели, мы можем использовать следующие два метода: -

  • использовать SetTitleTextAttributes : - это отлично работает на элементах кнопок панели, таких как" готово"," сохранить " и т. д. Однако он не работает с такими элементами, как Add, Trash symbol и т. д.(по крайней мере, не для меня), поскольку они не являются текстами.
  • использовать TintColor : - Если у меня есть элемент кнопки панели называется "удалитьна" :-

скрыть кнопку, я использовал следующий код:-

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

чтобы снова показать кнопку, я использовал следующий код: -

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

вот простой подход:

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

Я просто запустил его на своем iPad retina, и .01 достаточно мал, чтобы он не появился.


можно скрыть кнопку на месте, не изменяя ее ширину или не удаляя ее из панели. Если вы установите стиль равным, удалите заголовок и отключите кнопку, он исчезнет. Чтобы восстановить его, просто отмените изменения.

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

ниже-это мое решение, хотя я искал его для навигации.

navBar.topItem.rightBarButtonItem = nil;

здесь "navBar" - это IBOutlet к NavigationBar в представлении в XIB Здесь я хотел скрыть кнопку или показать ее на основе некоторого условия. Поэтому я тестирую условие в "If", и если true, я устанавливаю кнопку на ноль в методе viewDidLoad целевого представления.

Это может не иметь отношения к вашей проблеме, но что-то подобное, если вы хотите скрыть кнопки на Виджет navigationbar


в настоящее время я запускаю OS X Yosemite Developer Preview 7 и Xcode 6 beta 6 для iOS 7.1 и следующее решение отлично работает для меня:

  • создать отдушину для UINavigationItemи UIBarButtonItems
  • выполнить следующий код, чтобы удалить

    [self.navItem setRightBarButtonItem:nil];
    [self.navItem setLeftBarButtonItem:nil];
    
  • запустите следующие коды, чтобы снова добавить кнопки

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

для 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


я использовал IBOutlets в своем проекте. Так что мое решение было:

@IBOutlet weak var addBarButton: UIBarButtonItem!

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

и когда вам нужно будет снова показать эту панель, просто установите обратные свойства.

на Swift 3 вместо enable использовать isEnable собственность.


iOS 8. UIBarButtonItem с пользовательским изображением. Пробовал много разных способов, большинство из них не помогал. Решение Макса,setTintColor не менялся ни на какой цвет. Я сам это понял, подумал, что это кому-то пригодится.

Для Сокрытия:

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

Показывать:

[self.navigationItem.rightBarButtonItem setEnabled:YES];
[self.navigationItem.rightBarButtonItem setImage:image];

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


попробуйте Свифт, не обновляйте tintColor если у вас есть какой-то дизайн для вашего UIBarButtonItem как размер шрифта в AppDelegate, он полностью изменит внешний вид вашей кнопки при появлении.

в случае текстовой кнопки изменение заголовка может позволить вашей кнопке "исчезнуть".

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

@IBDesignable class AttributedBarButtonItem: UIBarButtonItem {

    var isHidden: Bool = false {

        didSet {

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

а теперь просто изменить isHidden собственность.


я обнаружил еще одну проблему в tintColor и isEnabled подход, предложенный Max и другими - когда 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

наличие элемента кнопки панели по-прежнему занимает место не было проблемой в моем случае, так как мы скрывали/показывали большинство элементов правой кнопки панели.


нет способа "скрыть" UIBarButtonItem вы должны удалить его из супервизора и добавить его обратно, когда вы хотите отобразить его снова.


улучшение от @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];

Это длинный путь вниз по списку ответов, но на всякий случай, если кто-то хочет легко скопировать и вставить для быстрого решения, вот он

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

один из способов сделать это использовать initWithCustomView:(UIView *) свойство при выделении UIBarButtonItem. Подкласс для UIView будет иметь свойство hide/unhide.

например:

1. есть UIButton который вы хотите скрыть / отобразить.

2. сделать UIButtonкак пользовательский вид. Например:

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

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

3. вы можете Скрыть/показать myButton вы создали. [myButton setHidden:YES];


установка цвета текста в ясный цвет, когда элемент кнопки панели отключен, вероятно, является более чистым вариантом. Нет никакой странности, которую вы должны объяснить в комментарии. Также вы не уничтожаете кнопку, поэтому вы все еще сохраняете связанные сегменты раскадровки.

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

затем, когда вы хотите, чтобы элемент кнопки панели скрыт, вы можете просто сделать:

self.navigationItem.rightBarButton.enabled = NO;

это хромает, нет никакого скрытого свойства, но это дает тот же результат.


если UIBarButtonItem имеет изображение вместо текста в нем, вы можете сделать это, чтобы скрыть его: navigationBar.topItem.rightBarButtonItem.customView.alpha = 0.0;


некоторые вспомогательные методы, которые я думал, что поделюсь на основе принятого ответа 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];
    }
}

вы можете легко получить представление и скрыть его таким образом

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

дополняя ответ Эли Берка, если ваш 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];
    }
}

для версии Swift, вот код:

на UINavigationBar:

self.navigationItem.rightBarButtonItem = nil

self.navigationItem.leftBarButtonItem = nil

Если вы используете Swift 3

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

Просто Набор barButton.customView = UIView() и увидеть трюк


вот расширение, которое будет обрабатывать это.

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

вам нужно управлять панелью инструментов.массив элементов.

вот код, который я использую, чтобы скрыть и отобразить кнопку Готово. Если ваша кнопка находится на крайнем краю панели инструментов или между другими кнопками, другие кнопки будут перемещаться, поэтому, если вы хотите, чтобы ваша кнопка просто исчезла, поместите свою кнопку в качестве последней кнопки в центр. Я анимирую движение кнопки для эффекта, мне это очень нравится.

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

В IB, если вы оставите кнопки заголовка пустым, он не появится (никогда не инициализируется?). Я часто делаю это во время разработки во время обновлений пользовательского интерфейса, если я хочу, чтобы элемент кнопки панели temp исчез для сборки, не удаляя его и не уничтожая все его ссылки на розетки.

Это не имеет такого же эффекта во время выполнения, установка заголовка кнопки на ноль не приведет к тому, что вся кнопка исчезнет. Извините, не совсем ответ на ваш вопрос, но может быть полезно некоторые.

Edit: этот трюк работает только в том случае, если стиль кнопки установлен в plain


Я добавлю свое решение здесь, поскольку я еще не мог найти его здесь. У меня есть динамическая кнопка, изображение которой зависит от состояния одного элемента управления. Самым простым решением для меня было установить изображение в nil Если элемент управления не присутствовал. Изображение обновлялось каждый раз, когда обновлялся элемент управления, и, таким образом, это было оптимальным для меня. Просто чтобы убедиться, что я также установил enabled to NO.

установка минимального значения ширины не работала на iOS 7.


с кредитом @lnafziger, @MindSpiker, @vishal, et. Эл,

самый простой один лайнер, который я прибыл для одной правой (или левой) кнопки панели:

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).