2009-02-11 6 views
8

J'ai une application NavigationBar avec deux vues: un parent et une vue secondaire. De l'avis sous j'ajouter un bouton à la droite comme suit:Comment changer l'image et désactiver UIBarButtonItem

- (void)viewDidLoad { 
    UIBarButtonItem *tempButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"lock-unlocked.png"] style:UIBarButtonItemStylePlain target:self action:@selector(lockScreen)]; 
    self.navigationItem.rightBarButtonItem = tempButton; 
    [tempButton release]; 
} 

Lorsque ce bouton est cliqué, je veux changer l'image de cette rightBarButtonItem et désactiver le leftBarButtonItem (qui a été ajouté automatiquement par le contrôleur). Fondamentalement avoir deux états d'un bouton, verrouillé et déverrouillé.

Question 1: La seule façon que je peux trouver comment changer l'image est de créer un nouvel UIButtonItem avec une nouvelle image et remplacer rightBarButtonItem avec ce nouveau. Mais je me demande s'il y a un moyen de simplement changer l'image sans créer un nouvel UIBarButtonItem. Est-ce que je crée une fuite de mémoire si je continue à créer un nouvel UIBarButtonItem?

Question 2: Comment mettre la main sur self.navigationItem.leftBarButtonItem et le désactiver/l'activer? Je ne crée pas celui-là manuellement, il est créé automatiquement pour moi par le contrôleur. Je ne vois aucune méthode/propriété sur UIBarButtonItem pour activer/désactiver l'interaction de l'utilisateur avec elle.

Répondre

18

Question 1: déclarer UIBarButtonItem * tempButton dans l'interface

@interface MyAppDelegate : NSObject <UIApplicationDelegate> { 
    UIBarButtonItem *tempButton; 
} 

@property (nonatomic, retain) UIBarButtonItem *tempButton; 

et synthétiser dans la mise en œuvre.

@synthesize tempButton; 

Créer l'objet dans viewDidLoad semblable à comment vous êtes maintenant.

- (void)viewDidLoad { 
    tempButtom = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"lock-unlocked.png"] style:UIBarButtonItemStylePlain target:self action:@selector(lockScreen)]; 
    self.navigationItem.rightBarButtonItem = tempButton; 
} 

Mais ne le relâchez pas ici, libérez-le dans la méthode dealloc normalement trouvée en bas.

Puis, quand LockScreen est appelé do

tempButton.image = [UIImage imageNamed:@"myImage.png"] 

Je n'ai pas de réponse à la question 2, im peur!

+1

Cette approche est beaucoup mieux. Merci! –

+3

Un petit problème pour le 3ème morceau de code: vous pouvez libérer tempButton après alloc car il a déjà été conservé lorsque vous le déclarez comme une propriété. –

+0

en fait iPhoney. parce qu'il n'a pas appelé self.tempButton, la propriété ne sera pas conservée. conserver la propriété ne peut être déclenchée que si vous utilisez self.VAR –

7

En ce qui concerne la question 2, utilisez le « permis » propriété:

self.navigationItem.leftBarButtonItem.enabled = NO; 
5

Je ne peux pas comprendre si vous avez un NavigationController, mais dans ce cas pour désactiver le bouton de retour, vous devez appeler:

self.navigationItem.hidesBackButton = YES; 
+0

Ne sera-ce pas cacher plutôt que de désactiver le bouton? –

0

je ne pouvais désactiver/gris sur un bouton NavBar avec:

self.navigationItem.leftBarButtonItem.enabled = NO; 

... mais cacher la le bouton de retour fonctionne bien!

self.navigationItem.hidesBackButton = YES; 

Merci Dzamir!

0

L'utilisation de "hidesBackButton = YES" n'est vraiment pas une solution élégante, car elle cache le bouton qui n'est pas ce que nous voulons. Une solution de rechange acceptable serait d'ajouter un UILabel à la fenêtre juste au-dessus du bouton de retour, au moins en désactivant les touches du bouton.

Ajouter cette méthode à votre classe AppDelegate:

- (void) disableLeftBarButtonItemOnNavbar:(BOOL)disable 
{ 
    static UILabel *l = nil; 

    if (disable) { 
     if (l != nil) 
      return; 
     l = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, 160, 44)]; 
     l.backgroundColor = [UIColor clearColor]; 
     l.userInteractionEnabled = YES; 
     [self.window addSubview:l]; 
    } 
    else { 
     if (l == nil) 
      return; 
     [l removeFromSuperview]; 
     [l release]; 
     l = nil; 
    } 
} 

Vous pouvez l'appeler comme celui-ci de tout contrôleur de vue pour désactiver:

MyAppDelegate *appDeleg = (MyAppDelegate *) [[UIApplication sharedApplication] delegate]; 
[appDeleg disableLeftBarButtonItemOnNavbar:YES]; 

Pour activer:

MyAppDelegate *appDeleg = (MyAppDelegate *) [[UIApplication sharedApplication] delegate]; 
[appDeleg disableLeftBarButtonItemOnNavbar:NO]; 
1

shouldn 't le ci-dessus ont libéré le UILabel * l après l'appel de [self.window addSubView: l]? De cette façon, il est conservé +1 lorsqu'il est ajouté à la sous-vue, mais relâché -1 dans la même branche. Sinon, vous devez appeler disableLeftBarButtonItemOnNavbar: NO pour le libérer. Et bien, vous finirez au même endroit à la fin, vous ne fuyez pas, je pense que les outils d'analyse statique qu'ils ont construits dans XCode n'aimeraient pas que ce soit dans une branche séparée. Petit détail :-)

- (void) disableLeftBarButtonItemOnNavbar:(BOOL)disable 
{ 
    static UILabel *l = nil; 

    if (disable) { 
     if (l != nil) 
      return; 
     l = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, 160, 44)]; 
     l.backgroundColor = [UIColor clearColor]; 
     l.userInteractionEnabled = YES; 
     [self.window addSubview:l]; 
     [l release]; 
    } 
    else { 
     if (l == nil) 
      return; 
     [l removeFromSuperview]; 
     l = nil; 
    } 
} 
0

Je pense que ce code vous aide,

UIButton *m_objbtnFlip= [[UIButton alloc] initWithFrame:CGRectMake(0,0,89, 37)]; 
    [m_objbtnFlip setBackgroundImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"btn_purchased" 
                           ofType:IMAGETYPE]] 
         forState:UIControlStateNormal]; 
    [m_objbtnFlip setBackgroundImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"btn_allavailable" 
                           ofType:IMAGETYPE]] 
         forState:UIControlStateSelected]; 
    [m_objbtnFlip addTarget:self action:@selector(flipViews) forControlEvents:UIControlEventTouchUpInside]; 

    UIBarButtonItem *objBarButtonItemRight = [[UIBarButtonItem alloc] initWithCustomView:m_objbtnFlip]; 

    self.navigationItem.rightBarButtonItem=objBarButtonItemRight; 
    [objBarButtonItemRight release]; 
    objBarButtonItemRight = nil; 

Et écrire action ici,

-(void)flipViews { 
    // put action code here 
} 
Questions connexes