web-dev-qa-db-fra.com

Comment afficher / masquer un UIBarButtonItem?

J'ai créé une barre d'outils dans IB avec plusieurs boutons. J'aimerais pouvoir masquer/afficher l'un des boutons en fonction de l'état des données dans la fenêtre principale.

UIBarButtonItem n'a pas de propriété masquée, et tous les exemples que j'ai trouvés jusqu'à présent pour les masquer impliquent de régler les boutons de la barre de navigation sur nil, ce que je ne pense pas vouloir faire ici car je pourrais avoir besoin de le montrer. Cliquez à nouveau sur le bouton (sans parler de cela, si je connecte mon bouton à un IBOutlet, si je le règle sur nil, je ne sais pas comment je le récupérerai).

243
Sasha

Enregistrez votre bouton dans une forte sortie (appelons-le myButton) et procédez comme suit pour l'ajouter ou le supprimer:

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

Comme il est stocké dans la prise, vous conserverez une référence même si ce n’est pas dans la barre d’outils.

256
lnafziger

Je sais que cette réponse est en retard pour cette question. Cependant, cela pourrait aider si quelqu'un d'autre faisait face à une situation similaire.

Dans iOS 7, pour masquer un élément de bouton de barre, nous pouvons utiliser les deux techniques suivantes: -

  • use SetTitleTextAttributes: - Cela fonctionne très bien sur les boutons tels que "Terminé", "Enregistrer", etc. des textes.
  • use TintColor: - Si j'ai un bouton appelé "deleteButton": -

Pour masquer le bouton, j'ai utilisé le code suivant: -

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

Pour afficher à nouveau le bouton, j'ai utilisé le code suivant: -

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

Voici une approche simple:

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

Je viens de le lancer sur mon iPad avec rétine, et .01 est suffisamment petit pour ne pas apparaître.

68
Drew Rosenberg

Il est possible de cacher un bouton en place sans en changer la largeur ni le supprimer de la barre. Si vous définissez le style sur plain, supprimez le titre et désactivez le bouton, il disparaîtra. Pour le restaurer, inversez simplement vos modifications.

-(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;
    }
}
59
Eli Burke

Ci-dessous, ma solution, mais je le cherchais pour la barre de navigation.

navBar.topItem.rightBarButtonItem = nil;

Ici "navBar" est un IBOutlet pour la NavigationBar dans la vue dans XIB Ici, je voulais cacher le bouton ou l'afficher en fonction de certaines conditions. Je teste donc la condition dans "Si" et si la valeur est true, je règle le bouton sur nil dans la méthode viewDidLoad de la vue cible.

Cela peut ne pas être pertinent pour votre problème, mais quelque chose de similaire si vous voulez masquer les boutons sur NavigationBar

42
vishal dharankar

Pour Swift 3 et Swift 4, vous pouvez le faire pour masquer la UIBarButtomItem:

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

Et pour montrer le UIBarButtonItem:

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

Sur le tintColor vous devez spécifier la couleur d'origine que vous utilisez pour le UIBarButtomItem

25
pableiros

J'utilise actuellement OS X Yosemite Developer Preview 7 et Xcode 6 beta 6, ciblant iOS 7.1 et les solutions suivantes me convenant parfaitement:

  • Créer un point de vente pour UINavigationItemet UIBarButtonItems
  • Exécutez le code suivant pour supprimer

    [self.navItem setRightBarButtonItem:nil];
    [self.navItem setLeftBarButtonItem:nil];
    
  • Exécutez les codes suivants pour ajouter des boutons à nouveau

    [self.navItem setRightBarButtonItem:deleteItem];
    [self.navItem setLeftBarButtonItem:addItem];
    
22
Olcay Ertaş

J'ai utilisé IBOutlets dans mon projet. Donc ma solution était:

@IBOutlet weak var addBarButton: UIBarButtonItem!

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

Et lorsque vous devrez afficher à nouveau cette barre, définissez simplement les propriétés inversées.

Dans Swift à la place enable utilisez la propriété isEnable.

14
Den

iOS 8. UIBarButtonItem avec une image personnalisée. Essayé de nombreuses manières différentes, la plupart n’aidaient pas. La solution de Max, thesetTintColor ne changeait pas de couleur. J'ai compris celui-ci moi-même, j'ai pensé qu'il pourrait être utile à quelqu'un.

Pour se cacher:

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

Pour montrer:

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

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

12
Dmitry Semenyuk

Essayez dans Swift, ne mettez pas à jour la tintColor si vous avez un design pour votre UIBarButtonItem comme la taille de la police dans AppDelegate, cela changera totalement l'apparence de votre bouton lors de son affichage.

Dans le cas d’un bouton texte, le changement de titre peut laisser votre bouton "disparaître".

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

J'ai découvert une autre ride dans l'approche tintColor et isEnabled proposée par Max et d'autres personnes - lorsque VoiceOver est activé pour l'accessibilité et que le bouton est logiquement masqué, le curseur d'accessibilité reste toujours actif sur le bouton de la barre, et indiquez qu’il est "estompé" (c’est-à-dire que isEnabled est défini sur false). L’approche de la réponse acceptée ne souffre pas de cet effet secondaire, mais j’ai trouvé un autre moyen de contourner le problème: définir isAccessibilityElement sur false pour "masquer" le bouton:

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

Puis, remettez isAccessibilityElement à nouveau lorsque vous "affichez" le bouton:

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

Avoir le bouton de barre toujours occuper encore de la place n'était pas un problème dans mon cas, puisque nous cachions/montrions la partie la plus à gauche des éléments du bouton de barre de droite.

6
Evan Kirkwood
@IBDesignable class AttributedBarButtonItem: UIBarButtonItem {

    var isHidden: Bool = false {

        didSet {

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

Et maintenant, changez simplement la propriété isHidden.

Améliorer la réponse de @ lnafziger

Enregistrez vos Barbuttons dans un sortie forte et faites ceci pour le cacher/le montrer:

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

Si nécessaire, utilisez ci-dessous Fonction ..

[self showBarButtonItem:self.rightBarBtn1];
[self hideBarButtonItem:self.rightBarBtn1];
5
umakanta

Il n’existe aucun moyen de "masquer" un UIBarButtonItem; vous devez le supprimer de la superView et le rajouter lorsque vous souhaitez le réafficher.

4
Kyle Richter

Ceci est loin dans la liste des réponses, mais juste au cas où quelqu'un voudrait un copier-coller facile pour la solution Swift, la voici

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

Une façon de le faire consiste à utiliser la propriété initWithCustomView:(UIView *) de lors de l'affectation de UIBarButtonItem. La sous-classe pour UIView aura la propriété masquer/afficher.

Par exemple:

1. Ayez une UIButton que vous voulez masquer/afficher.

2. Rendre la UIButtonde la vue personnalisée. Comme :

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

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

. Vous pouvez masquer/afficher la myButton que vous avez créée. [myButton setHidden:YES];

3
iNoob

Définir la couleur du texte sur une couleur claire lorsque l'élément de bouton à barres est désactivé est probablement une option plus propre. Il n'y a pas d'étrangeté à expliquer dans un commentaire. De plus, vous ne détruisez pas le bouton, vous conservez donc toutes les légendes associées au story-board.

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

Ensuite, chaque fois que vous souhaitez masquer l'élément de bouton de barre, vous pouvez simplement faire:

self.navigationItem.rightBarButton.enabled = NO;

C'est nul, il n'y a pas de propriété cachée mais cela offre le même résultat.

2
puppybits

Si UIBarButtonItem a une image à la place du texte, vous pouvez le faire pour le masquer: navigationBar.topItem.rightBarButtonItem.customView.alpha = 0.0;

2
Artem Goryaev

Si vous utilisez Swift

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

Certaines méthodes d'assistance que je pensais partager seraient basées sur la réponse acceptée d'Inafziger, car j'ai plusieurs barres d'outils et plusieurs boutons dans chacune d'elles:

-(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];
    }
}
2
Guy Lowe

Vous pouvez facilement obtenir la vue et la cacher de cette façon

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

Il suffit de définir barButton.customView = UIView() et de voir le tour

2
jeff ayan

Pour la version Swift, voici le code:

Pour UINavigationBar:

self.navigationItem.rightBarButtonItem = nil

self.navigationItem.leftBarButtonItem = nil
1
Sohil R. Memon

Pour compléter la réponse d’Eli Burke, si votre UIBarButtonItem a une image d’arrière-plan au lieu d’un titre, vous pouvez utiliser le code:

-(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];
    }
}
1
Renato Lochetti

Voici une extension qui va gérer ça.

extension UIBarButtonItem {

    var isHidden: Bool {
        get {
            return tintColor == .clear
        }
        set {
            tintColor = newValue ? .clear : .white //or whatever color you want
            isEnabled = !newValue
            isAccessibilityElement = !newValue
        }
    }

}

USAGE:

myBarButtonItem.isHidden = true
1
Harris

Dans IB, si vous laissez le titre du bouton vide, il n'apparaîtra pas (jamais initialisé?). Je le fais souvent pendant le développement lors des mises à jour de l'interface utilisateur si je souhaite qu'un élément de bouton de barre disparaisse temporairement pour une construction sans le supprimer ni supprimer toutes ses références de prise.

Cela n'a pas le même effet au moment de l'exécution. Définir le titre du bouton sur nil ne fera pas disparaître tout le bouton. Désolé ne répond pas vraiment à votre question, mais peut être utile à certains.

Edit: cette astuce ne fonctionne que si le style du bouton est défini sur plain

0
pretzels1337

J'ai travaillé avec xib et avec UIToolbar. BarButtonItem a été créé dans un fichier xib. J'ai créé IBOutlet pour BarButtonItem. Et j'ai utilisé ce code pour cacher mon BarButtonItem

 self.myBarButtonItem.enabled = NO;
 self.myBarButtonItem.title =  nil;

cela m'a aidé.

0
Malder

Je vais ajouter ma solution ici car je ne pouvais pas le trouver mentionné ici pour le moment. J'ai un bouton dynamique dont l'image dépend de l'état d'un contrôle. La solution la plus simple pour moi était de régler l'image sur nil si le contrôle n'était pas présent. L'image était mise à jour à chaque fois que le contrôle était mis à jour, ce qui était optimal pour moi. Juste pour être sûr, je règle également la enabled sur NO.

La définition de la largeur sur une valeur minimale ne fonctionnait pas sous iOS 7.

0
mkko

Avec le crédit de @lnafziger, @MindSpiker, @vishal, et. Al,

Le revêtement le plus simple auquel je suis arrivé pour un bouton de barre droit (ou gauche) est le suivant:

self.navigationItem.rightBarButtonItem = <#StateExpression#>
    ? <#StrongPropertyButton#> : nil;

Un péché:

@interface MyClass()

@property (strong, nonatomic) IBOutlet UIBarButtonItem *<#StrongPropertyButton#>;

@end

@implementation

- (void) updateState
{
    self.navigationItem.rightBarButtonItem = <#StateExpression#>
        ? <#StrongPropertyButton#> : nil;
}

@end

J'ai testé cela et cela fonctionne pour moi (avec l'élément de bouton de barre forte câblé via IB).

0
Chris Conover

Vous devez manipuler le tableau toolbar.items.

Voici un code que j'utilise pour masquer et afficher un bouton Terminé. Si votre bouton est à l'extrême bord de la barre d'outils ou entre d'autres boutons, vos autres boutons se déplaceront. Si vous souhaitez que votre bouton disparaisse, placez-le comme dernier bouton vers le centre. J'anime le bouton pour l'effet, je l'aime bien.

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

}

alors maintenant peut utiliser le code suivant pour afficher votre bouton

[self.libraryToolbar setItems:libraryToolbarDocumentManagementEnabled animated:YES];
trashCan.enabled = YES;
mail.enabled = YES; 

ou pour cacher votre bouton

[self.libraryToolbar setItems:libraryToolbarDocumentManagementDisabled animated:YES];
trashCan.enabled = NO;
mail.enabled = NO;
0
Graham

Vous pouvez utiliser des attributs de texte pour masquer un bouton de barre:

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

Voir aussi ma solution avec l'extension UIBarButtonItem pour la même question: Faire disparaître un UIBarButtonItem en utilisant Swift IOS

0
iUrii

Sous-classe UIBarButtonItem. Assurez-vous que le bouton dans Interface Builder est défini sur HidableBarButtonItem. Faites un point de vente du bouton au contrôleur de vue. Depuis le contrôleur de vue, vous pouvez alors masquer/afficher le bouton en appelant setHidden:

HidableBarButtonItem.h

#import <UIKit/UIKit.h>

@interface HidableBarButtonItem : UIBarButtonItem

@property (nonatomic) BOOL hidden;

@end

HidableBarButtonItem.m

#import "HidableBarButtonItem.h"

@implementation HidableBarButtonItem

- (void)setHidden:(BOOL const)hidden {
    _hidden = hidden;

    self.enabled = hidden ? YES : NO;
    self.tintColor = hidden ? [UIApplication sharedApplication].keyWindow.tintColor : [UIColor clearColor];
}

@end
0

pour cacher l'un des nombreux éléments, j'ai utilisé le code suivant:

self.navigationItem.leftBarButtonItems?.remove(at: 0)  
self.navigationItem.rightBarButtonItems?.remove(at: 1)

Je suppose que les articles peuvent être rajoutés si nécessaire.

0
Atara