Как показать/скрыть UIBarButtonItem?

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

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

Ответ 1

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

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

Ответ 2

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

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

  • use SetTitleTextAttributes: - Это отлично работает на элементах панели, таких как "Готово", "Сохранить" и т.д. Однако это не работает с такими элементами, как "Добавить", "Корзина" и т.д. (по крайней мере, не для меня), так как они а не тексты.
  • use TintColor: - Если у меня есть элемент кнопки панели, называемый "deleteButton": -

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

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

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

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

Ответ 3

Здесь простой подход:

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

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

Ответ 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;
    }
}

Ответ 5

Ниже мое решение, хотя я смотрел его на панель навигации.

navBar.topItem.rightBarButtonItem = nil;

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

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

Ответ 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

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

  • Создать выход для UINavigationItem и UIBarButtonItem s
  • Выполните следующий код для удаления

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

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

Ответ 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 с пользовательским изображением. Пробовал много разных способов, большинство из них не помогало. Максимальное решение, setTintColor не менялось ни на один цвет. Я сам это понял, подумал, что это будет полезно для кого-то.

Для скрытия:

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

Для показа:

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

Ответ 11

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

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

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

Ответ 12

@IBDesignable class AttributedBarButtonItem: UIBarButtonItem {

    var isHidden: Bool = false {

        didSet {

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

И теперь просто измените свойство isHidden.

Ответ 13

Я обнаружил еще одну tintColor подходе tintColor и isEnabled предложенном Максом и другими, - когда VoiceOver включен для доступности, а кнопка логически скрыта, курсор доступности по-прежнему будет фокусироваться на кнопке панели и утверждать, что она "затемнена" (т.е. потому что isEnabled имеет значение false). Подход в принятом ответе не страдает от этого побочного эффекта, но я обнаружил, что при работе с "скрытием" кнопки для isAccessibilityElement было установлено isAccessibilityElement false:

deleteButton.tintColor = UIColor.clear
deleteButton.isEnabled = false
deleteButton.isAccessibilityElement = false

И затем установка isAccessibilityElement обратно в true при "показе" кнопки:

deleteButton.tintColor = UIColor.blue
deleteButton.isEnabled = true
deleteButton.isAccessibilityElement = true

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

Ответ 14

Улучшение От ответа @lnafziger

Сохраните свои Барбуты в сильной розетке и сделайте это, чтобы скрыть/показать его:

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

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

Ответ 16

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

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

Ответ 17

Один из способов сделать это - использовать свойство 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];

Ответ 18

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

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

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

self.navigationItem.rightBarButton.enabled = NO;

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

Ответ 19

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

Ответ 20

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

Ответ 21

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

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

Ответ 22

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

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

Ответ 23

Просто установите barButton.customView = UIView() и просмотрите Trick

Ответ 24

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

Для версии Swift приведен код:

Для UINavigationBar:

self.navigationItem.rightBarButtonItem = nil

self.navigationItem.leftBarButtonItem = nil

Ответ 26

Вот расширение, которое справится с этим.

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

Ответ 27

Вам нужно манипулировать массивом 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;

Ответ 28

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

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

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

Ответ 29

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

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

Ответ 30

С благодарностью @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).