Как показать / скрыть UIBarButtonItem?
Я создал панель инструментов в IB с несколькими кнопками. Я хотел бы иметь возможность скрыть / показать одну из кнопок в зависимости от состояния данных в главном окне.
UIBarButtonItem
не имеет скрытого свойства, и любые примеры, которые я нашел до сих пор для сокрытия их, включают установку кнопок навигационной панели в ноль, что я не думаю, что я хочу делать здесь, потому что мне может понадобиться снова показать кнопку (не упомянуть, что, если я подключу свою кнопку к IBOutlet, если я установлю это на ноль, я не уверен, как я получу это назад).
39 ответов
Сохраните кнопку в надежной розетке (назовем ее 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
: - Это прекрасно работает с кнопками панели, такими как "Готово", "Сохранить" и т. Д. Однако, это не работает с такими элементами, как "Добавить", "Корзина" и т. Д.(По крайней мере, не для меня), поскольку они не являются текстами. - использование
TintColor
: - Если у меня есть элемент кнопки панели под названием "deleteButton":-
Чтобы скрыть кнопку, я использовал следующий код: -
[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, а 0,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 для Navigation Bar в представлении в XIB. Здесь я хотел скрыть кнопку или показать ее в зависимости от некоторых условий. Поэтому я проверяю условие в "Если", и если true, я устанавливаю кнопку в ноль в методе viewDidLoad целевого представления.
Это может не относиться к вашей проблеме, но что-то похожее, если вы хотите скрыть кнопки на панели навигации
Для 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
В настоящее время я использую 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];
Я использовал IBOutlets в своем проекте. Итак, мое решение было:
@IBOutlet weak var addBarButton: UIBarButtonItem!
addBarButton.enabled = false
addBarButton.tintColor = UIColor.clearColor()
И когда вам нужно будет снова показать эту панель, просто установите обратные свойства.
В Swift 3 вместо enable
использование isEnable
имущество.
self.dismissButton.customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
iOS 8. UIBarButtonItem с пользовательским изображением. Перепробовал много разных способов, большинство из них не помогало. Решение Макса,setTintColor
не менялся ни на какой цвет. Я сам понял это, подумал, что это кому-нибудь пригодится.
Для сокрытия:
[self.navigationItem.rightBarButtonItem setEnabled:NO];
[self.navigationItem.rightBarButtonItem setImage:nil];
Для показа:
[self.navigationItem.rightBarButtonItem setEnabled:YES];
[self.navigationItem.rightBarButtonItem setImage:image];
Я обнаружил еще одну морщину в tintColor
а также isEnabled
Подход, предложенный Максом и другими, - когда VoiceOver включен для специальных возможностей, а кнопка логически скрыта, курсор специальных возможностей все еще фокусируется на кнопке панели и заявляет, что она "затемнена" (т. е. потому что isEnabled
установлено в false). Подход в принятом ответе не страдает от этого побочного эффекта, но я обнаружил, что нужно было еще обойти isAccessibilityElement
ложь, когда "прячешь" кнопку:
deleteButton.tintColor = UIColor.clear
deleteButton.isEnabled = false
deleteButton.isAccessibilityElement = false
А потом настройка isAccessibilityElement
Вернуться к истине, когда "показывает" кнопку:
deleteButton.tintColor = UIColor.blue
deleteButton.isEnabled = true
deleteButton.isAccessibilityElement = true
В моем случае не было проблем с тем, чтобы элемент панели кнопок все еще занимал пространство, поскольку мы скрывали / отображали самые левые элементы панели справа.
Попробуйте в Swift, не обновляйте tintColor
если у вас есть какой-то дизайн для вашего UIBarButtonItem, например размер шрифта в AppDelegate, он полностью изменит внешний вид вашей кнопки при отображении.
В случае текстовой кнопки, изменение заголовка может позволить вашей кнопке "исчезнуть".
if WANT_TO_SHOW {
myBarButtonItem.enabled = true
myBarButtonItem.title = "BUTTON_NAME"
}else{
myBarButtonItem.enabled = false
myBarButtonItem.title = ""
}
Вот расширение, которое справится с этим.
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
@IBDesignable class AttributedBarButtonItem: UIBarButtonItem {
var isHidden: Bool = false {
didSet {
isEnabled = !isHidden
tintColor = isHidden ? UIColor.clear : UIColor.black
}
}
}
А теперь просто поменяй isHidden
имущество.
Совершенствование От @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];
Просто установите barButton.customView = UIView()
и увидеть трюк
Нет способа "спрятать" UIBarButtonItem, вы должны удалить его из superView и добавить его обратно, когда вы захотите отобразить его снова.
Это длинный путь вниз по списку ответов, но на случай, если кто-то захочет легко скопировать и вставить для быстрого решения, вот оно
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
будет иметь скрыть / показать свойство.
Например:
1. Иметь UIButton
который вы хотите скрыть / показать.
2. Сделать UIButton
как пользовательский вид. Подобно:
UIButton*myButton=[UIButton buttonWithType:UIButtonTypeRoundedRect];//your button
UIBarButtonItem*yourBarButton=[[UIBarButtonItem alloc] initWithCustomView:myButton];
3. Вы можете скрыть / показать myButton
вы создали [myButton setHidden:YES];
Наконец, начиная с iOS 16+ ,UIBarButtonItem
имеетisHidden
свойство.
Итак, чтобы расширить существующие ответы, что-то вроде
extension UIBarButtonItem {
func show() {
if #available(iOS 16.0, *) {
isHidden = false
} else {
isEnabled = true
tintColor = .white
}
}
func hide() {
if #available(iOS 16.0, *) {
isHidden = true
} else {
isEnabled = false
tintColor = .clear
}
}
}
Для версии 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
}
Если в UIBarButtonItem вместо текста есть изображение, вы можете сделать это, чтобы скрыть его: navigationBar.topItem.rightBarButtonItem.customView.alpha = 0.0;
Установка цвета текста в прозрачный цвет, когда элемент панели кнопок отключен, возможно, более чистый вариант. Там нет странностей, которые вы должны объяснить в комментарии. Также вы не уничтожаете кнопку, поэтому сохраняете любые связанные с ней раскадровки.
[self.navigationItem.rightBarButtonItem setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor clearColor]}
forState:UIControlStateDisabled];
Затем, когда вы захотите скрыть элемент панели кнопок, вы можете просто сделать:
self.navigationItem.rightBarButton.enabled = NO;
Жаль, что нет скрытого свойства, но это дает тот же результат.
Вы можете легко получить вид и скрыть это таким образом
let view: UIView = barButtonItem.valueForKey("view") as! UIView
view.hidden = true
Некоторые вспомогательные методы, которыми я поделился, основываясь на принятом ответе 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];
}
}
Справочный ответ @haste
extension UIBarButtonItem {
var isHidden: Bool {
set {
if #available(iOS 16.0, *) {
isHidden = newValue
} else {
isEnabled = !newValue
tintColor = newValue ? .clear : nil
}
}
get {
if #available(iOS 16.0, *) {
return isHidden
} else {
return isEnabled == false && tintColor == .clear
}
}
}
}
Вы можете использовать атрибуты текста, чтобы скрыть кнопку панели:
barButton.enabled = false
barButton.setTitleTextAttributes([NSForegroundColorAttributeName : UIColor.clearColor()], forState: .Normal)
Также посмотрите мое решение с расширением UIBarButtonItem для аналогичного вопроса: сделать UIBarButtonItem исчезнуть с помощью быстрой IOS
Дополняя ответ Эли Бёрка, если ваш 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];
}
}
У меня была проблема, что у меня было 2 leftBarButtonItems. На Mac Catalyst firstButton указывал на действие, которое не поддерживалось: запись видео с помощью AVFoundation. На Mac Catalyst действовала только вторая кнопка: используйте UIImagePickerController.
Итак, на Mac Catalyst мне пришлось указать первый UIBarButtonItem на secondButton и всегда скрыть второй UIBarButtonItem. На iOS должны отображаться обе кнопки. Это было моим решением:
#if TARGET_OS_MACCATALYST
self.navigationItem.leftBarButtonItem = self.secondButton;
NSUInteger count = [self.navigationItem.leftBarButtonItems count];
for (NSUInteger i = 0; i < count; i++) {
UIBarButtonItem *thisButton = [self.navigationItem.leftBarButtonItems objectAtIndex:i];
if (i == 1) {
thisButton.enabled = NO;
thisButton.tintColor = [UIColor clearColor];
}
}
#else
self.navigationItem.leftBarButtonItem = self.firstButton;
#endif
Надеюсь, это поможет кому-то с аналогичной проблемой.