ios - ¿Cómo muestro/oculto un UIBarButtonItem?
uitoolbar (30)
He creado una barra de herramientas en IB con varios botones. Me gustaría poder ocultar / mostrar uno de los botones dependiendo del estado de los datos en la ventana principal.
UIBarButtonItem
no tiene una propiedad oculta, y los ejemplos que he encontrado hasta ahora para ocultarlos implican configurar los botones de la barra de navegación en nil, lo cual no creo que quiera hacer aquí porque es posible que deba mostrar el botón nuevamente ( sin mencionar que, si conecto mi botón a un IBOutlet, si lo configuro a cero, no estoy seguro de cómo lo recuperaría).
A continuación se muestra mi solución, aunque la estaba buscando para la barra de navegación.
navBar.topItem.rightBarButtonItem = nil;
Aquí "navBar" es un IBOutlet a la barra de navegación en la vista en XIB. Aquí quería ocultar el botón o mostrarlo según alguna condición. Por lo tanto, estoy probando la condición en "Si" y si es verdadero, estoy configurando el botón a cero en el método viewDidLoad de la vista de destino.
Es posible que esto no sea relevante para su problema exactamente, pero es algo similar en caso de que desee ocultar los botones en la barra de navegación
Actualmente estoy ejecutando OS X Yosemite Developer Preview 7 y Xcode 6 beta 6 con iOS 7.1 y la siguiente solución funciona bien para mí:
- Crear salida para
UINavigationItem
yUIBarButtonItem
s Ejecutar el siguiente código para eliminar
[self.navItem setRightBarButtonItem:nil]; [self.navItem setLeftBarButtonItem:nil];
Ejecute los siguientes códigos para agregar botones nuevamente
[self.navItem setRightBarButtonItem:deleteItem]; [self.navItem setLeftBarButtonItem:addItem];
Agregaré mi solución aquí porque no la he encontrado mencionada aquí todavía. Tengo un botón dinámico cuya imagen depende del estado de un control. La solución más simple para mí fue establecer la imagen en nil
si el control no estaba presente. La imagen se actualizó cada vez que se actualizó el control y, por lo tanto, esto fue óptimo para mí. Solo para estar seguro de que también puse el enabled
en NO
.
Establecer el ancho a un valor mínimo no funcionó en iOS 7.
Algunos métodos de ayuda que pensé que compartiría según la respuesta aceptada de lnafziger, ya que tengo varias barras de herramientas y varios botones en cada una:
-(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];
}
}
Aquí hay un enfoque simple:
hide: barbuttonItem.width = 0.01;
show: barbuttonItem.width = 0; //(0 defaults to normal button width, which is the width of the text)
Acabo de ejecutarlo en mi retina iPad y .01 es lo suficientemente pequeño como para que no se muestre.
Aquí hay una extensión que manejará esto.
extension UIBarButtonItem {
var isHidden: Bool {
get {
return tintColor == .clear
}
set {
tintColor = newValue ? .clear : .white //or whatever color you want
isEnabled = !newValue
isAccessibilityElement = !newValue
}
}
}
USO:
myBarButtonItem.isHidden = true
Complementando la respuesta de Eli Burke, si su UIBarButtonItem
tiene una imagen de fondo en lugar de un título, puede usar el código:
-(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];
}
}
Con crédito para @lnafziger, @MindSpiker, @vishal, et. Alabama,
El forro más simple al que llegué para un solo botón de barra derecha (o izquierda) es:
self.navigationItem.rightBarButtonItem = <#StateExpression#>
? <#StrongPropertyButton#> : nil;
Como en:
@interface MyClass()
@property (strong, nonatomic) IBOutlet UIBarButtonItem *<#StrongPropertyButton#>;
@end
@implementation
- (void) updateState
{
self.navigationItem.rightBarButtonItem = <#StateExpression#>
? <#StrongPropertyButton#> : nil;
}
@end
Probé esto y funciona para mí (con el elemento de botón de barra fuerte conectado a través de IB).
Configurar el color del texto en un color claro cuando el elemento del botón de la barra está deshabilitado es probablemente una opción más limpia. No hay ninguna rareza que tengas que explicar en un comentario. Además, no destruyes el botón, por lo que aún mantienes los segmentos asociados del guión gráfico.
[self.navigationItem.rightBarButtonItem setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor clearColor]}
forState:UIControlStateDisabled];
Entonces, cuando quiera que desee ocultar el elemento del botón de la barra, simplemente puede hacer:
self.navigationItem.rightBarButton.enabled = NO;
Es cojo no hay propiedad oculta pero esto ofrece el mismo resultado.
Descubrí otra arruga en el enfoque tintColor
e isEnabled
sugerido por Max y otros: cuando VoiceOver está habilitado para accesibilidad y el botón está lógicamente oculto, el cursor de accesibilidad aún se enfocará en el botón de barra y el estado indicará que está "atenuado" (es decir, porque isEnabled
se establece en falso). El enfoque en la respuesta aceptada no sufre este efecto secundario, pero otra isAccessibilityElement
que encontré fue establecer isAccessibilityElement
en false cuando se "esconde" el botón:
deleteButton.tintColor = UIColor.clear
deleteButton.isEnabled = false
deleteButton.isAccessibilityElement = false
Y luego configurando isAccessibilityElement
nuevo a verdadero cuando "muestre" el botón:
deleteButton.tintColor = UIColor.blue
deleteButton.isEnabled = true
deleteButton.isAccessibilityElement = true
Tener el elemento del botón de la barra aún ocupando espacio no era un problema en mi caso, ya que estábamos ocultando / mostrando el elemento del botón de la barra derecha más a la izquierda.
En IB, si deja el título del botón en blanco, no aparecerá (¿nunca inicializado?). Hago esto a menudo durante el desarrollo durante las actualizaciones de la interfaz de usuario si deseo que un elemento del botón de la barra desaparezca temporalmente de una compilación sin eliminarla y eliminar todas sus referencias de salida.
Esto no tiene el mismo efecto durante el tiempo de ejecución, establecer el título del botón en nil no hará que todo el botón desaparezca. Lo siento realmente no responde a tu pregunta, pero puede ser útil para algunos.
Edición: este truco solo funciona si el estilo del botón se establece en plano
En caso de que UIBarButtonItem tenga una imagen en lugar del texto, puede hacer esto para ocultarla: navigationBar.topItem.rightBarButtonItem.customView.alpha = 0.0;
Es posible ocultar un botón en su lugar sin cambiar su ancho o eliminarlo de la barra. Si configura el estilo como simple, elimina el título y deshabilita el botón, desaparecerá. Para restaurarlo, simplemente revierta sus cambios.
-(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;
}
}
Esto está muy por debajo de la lista de respuestas, pero en caso de que alguien quiera copiar y pegar fácilmente para la solución rápida, aquí está
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);
}
}
Guarde su botón en una salida fuerte (llamémoslo myButton
) y haga esto para agregarlo / eliminarlo:
// 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];
}
Debido a que está almacenado en la salida, mantendrá una referencia a él incluso cuando no esté en la barra de herramientas.
Mejorando desde @lnafziger respuesta
Guarde sus Barbuttons en una salida fuerte y haga esto para ocultarlo / mostrarlo:
-(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];
}
}
Cuando se requiera usar debajo de la función
[self showBarButtonItem:self.rightBarBtn1];
[self hideBarButtonItem:self.rightBarBtn1];
Necesitas manipular la matriz toolbar.items.
Aquí hay un código que utilizo para ocultar y mostrar un botón Hecho. Si su botón está en el borde extremo de la barra de herramientas o entre otros botones, sus otros botones se moverán, así que si desea que su botón desaparezca, coloque el botón como último botón hacia el centro. Me animo el botón de movimiento para el efecto, me gusta bastante.
-(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];
}
Así que ahora puedes usar el siguiente código para mostrar tu botón.
[self.libraryToolbar setItems:libraryToolbarDocumentManagementEnabled animated:YES];
trashCan.enabled = YES;
mail.enabled = YES;
o para ocultar su botón
[self.libraryToolbar setItems:libraryToolbarDocumentManagementDisabled animated:YES];
trashCan.enabled = NO;
mail.enabled = NO;
No hay forma de "ocultar" un UIBarButtonItem, debe eliminarlo del superView y volver a agregarlo cuando desee volver a mostrarlo.
Para Swift 3 y Swift 4, puede hacer esto para ocultar el UIBarButtomItem
:
self.deleteButton.isEnabled = false
self.deleteButton.tintColor = UIColor.clear
Y para mostrar el UIBarButtonItem
:
self.deleteButton.isEnabled = true
self.deleteButton.tintColor = UIColor.blue
En el tintColor
debe tener que especificar el color de origen que está utilizando para el UIBarButtomItem
Para la versión Swift, aquí está el código:
Para UINavigationBar
:
self.navigationItem.rightBarButtonItem = nil
self.navigationItem.leftBarButtonItem = nil
Pruebe en Swift , no actualice el tintColor
si tiene algún diseño para su UIBarButtonItem como el tamaño de fuente en AppDelegate, cambiará totalmente la apariencia de su botón cuando aparezca.
En el caso de un botón de texto, cambiar el título puede hacer que su botón desaparezca.
if WANT_TO_SHOW {
myBarButtonItem.enabled = true
myBarButtonItem.title = "BUTTON_NAME"
}else{
myBarButtonItem.enabled = false
myBarButtonItem.title = ""
}
Puede obtener fácilmente la vista y ocultarla de esta manera
let view: UIView = barButtonItem.valueForKey("view") as! UIView
view.hidden = true
Sé que esta respuesta es tarde para esta pregunta. Sin embargo, podría ayudar si alguien más se enfrenta a una situación similar.
En iOS 7, para ocultar un elemento del botón de la barra, podemos usar las siguientes dos técnicas:
- use
SetTitleTextAttributes
: - Esto funciona muy bien en elementos del botón de la barra como "Hecho", "Guardar", etc. Sin embargo, no funciona en elementos como Agregar, Símbolo de Papelera, etc. (al menos no para mí) ya que no son textos. - use
TintColor
: - Si tengo un elemento de botón de barra llamado "deleteButton": -
Para ocultar el botón, utilicé el siguiente código:
[self.deleteButton setEnabled:NO];
[self.deleteButton setTintColor: [UIColor clearColor]];
Para mostrar el botón otra vez utilicé el siguiente código:
[self.deleteButton setEnabled:YES];
[self.deleteButton setTintColor:nil];
Solo establece barButton.customView = UIView()
y ve el truco
Una forma de hacerlo es usar la initWithCustomView:(UIView *)
de cuando se UIBarButtonItem
el UIBarButtonItem
. La subclase para UIView
tendrá propiedad de ocultar / ocultar.
Por ejemplo:
1. Tenga un UIButton
que quiera ocultar / mostrar.
2. Haga el UIButton
como la vista personalizada. Me gusta :
UIButton*myButton=[UIButton buttonWithType:UIButtonTypeRoundedRect];//your button
UIBarButtonItem*yourBarButton=[[UIBarButtonItem alloc] initWithCustomView:myButton];
3. Puedes ocultar / mostrar el myButton
que has creado. [myButton setHidden:YES];
Utilicé IBOutlets en mi proyecto. Así que mi solución fue:
@IBOutlet weak var addBarButton: UIBarButtonItem!
addBarButton.enabled = false
addBarButton.tintColor = UIColor.clearColor()
Y cuando necesite mostrar esta barra nuevamente, simplemente establezca las propiedades invertidas.
En Swift 3, en cambio, enable
uso de la propiedad isEnable
.
iOS 8. UIBarButtonItem con imagen personalizada. Probado de muchas maneras diferentes, la mayoría de ellos no estaban ayudando. La solución de Max, el setTintColor
no estaba cambiando a ningún color. Lo descubrí yo mismo, pensé que sería de utilidad para alguien.
Para la ocultación:
[self.navigationItem.rightBarButtonItem setEnabled:NO];
[self.navigationItem.rightBarButtonItem setImage:nil];
Para mostrar:
[self.navigationItem.rightBarButtonItem setEnabled:YES];
[self.navigationItem.rightBarButtonItem setImage:image];
self.dismissButton.customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
Si está utilizando Swift 3
if (ShowCondition){
self.navigationItem.rightBarButtonItem = self.addAsset_btn
}
else {
self.navigationItem.rightBarButtonItem = nil
}
@IBDesignable class AttributedBarButtonItem: UIBarButtonItem {
var isHidden: Bool = false {
didSet {
isEnabled = !isHidden
tintColor = isHidden ? UIColor.clear : UIColor.black
}
}
}
Y ahora simplemente cambia la propiedad isHidden
.