2009-02-11 3 views
8

Ho un'app NavigationBar con due viste: una parent e una vista secondaria. Nella vista sub Sto aggiungendo un pulsante alla destra come segue:Come cambiare immagine e disabilitare 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]; 
} 

Quando questo pulsante viene premuto voglio cambiare l'immagine di questo rightBarButtonItem e disattivare il leftBarButtonItem (che è stata aggiunta automaticamente dal controller). Fondamentalmente hanno due stati di un pulsante, bloccato e sbloccato.

Domanda 1: L'unico modo per trovare come modificare l'immagine è creare un nuovo UIButtonItem con una nuova immagine e sostituire rightBarButtonItem con quello nuovo. Ma mi chiedo se c'è un modo per cambiare semplicemente l'immagine senza creare un nuovo UIBarButtonItem. Sto creando una perdita di memoria se continuo a creare un nuovo UIBarButtonItem?

Domanda 2: Come posso ottenere una sospensione di self.navigationItem.leftBarButtonItem e disabilitarla/abilitarlo? Non lo creo manualmente, viene creato automaticamente dal controllore. Non vedo alcun metodo/proprietà su UIBarButtonItem per abilitare/disabilitare l'interazione dell'utente con esso.

risposta

18

Domanda 1: Dichiarare UIBarButtonItem * tempButton nell'interfaccia

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

@property (nonatomic, retain) UIBarButtonItem *tempButton; 

e sintetizzare nella sua attuazione.

@synthesize tempButton; 

Creare l'oggetto in viewDidLoad simile a come si è ora.

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

Ma non rilascialo qui, rilascialo nel metodo dealloc normalmente trovato nella parte inferiore.

Poi, quando LockScreen è chiamato fare

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

Non ho una risposta per la domanda 2, im paura!

+1

Questo approccio sembra molto meglio. Grazie! –

+3

Un piccolo problema per il terzo pezzo di codice: puoi rilasciare tempButton dopo l'allocazione perché è già stato mantenuto quando lo dichiari come proprietà. –

+0

effettivamente iPhoney. poiché non ha chiamato self.tempButton, la proprietà NON manterrà. mantenere la proprietà può essere attivata solo se si utilizza self.VAR –

7

In relazione al punto 2, utilizzare il 'permesso' immobile:

self.navigationItem.leftBarButtonItem.enabled = NO; 
5

Non riesco a capire se hai un navigationController, ma in questo caso per disabilitare il pulsante indietro è necessario chiamare:

self.navigationItem.hidesBackButton = YES; 
+0

Non nascondere questo piuttosto che disattivare il pulsante? –

0

non ero in grado di disattivare/grigio fuori un tasto NavBar con:

self.navigationItem.leftBarButtonItem.enabled = NO; 

... ma nascondendo la pulsante indietro funziona bene!

self.navigationItem.hidesBackButton = YES; 

Grazie Dzamir!

0

L'utilizzo di "hidesBackButton = SÌ" non è una soluzione elegante, perché nasconde il pulsante che non è quello che vogliamo. Un work-around accettabile sarebbe l'aggiunta di un UILabel alla finestra appena sopra il pulsante back, disabilitando almeno i tocchi sul pulsante.

Aggiungere questo metodo per la 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; 
    } 
} 

È possibile chiamare in questo modo da qualsiasi controller della vista per disabilitare:

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

Per attivare:

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

shouldn 'quanto sopra ha rilasciato UILabel * l dopo la chiamata [self.window addSubView: l]? In questo modo viene mantenuto +1 quando aggiunto alla sottoview, ma rilasciato -1 nello stesso ramo. Altrimenti, è necessario disabilitare disableLeftBarButtonItemOnNavbar: NO per rilasciarlo. E mentre finirai nello stesso posto alla fine, non perderai nulla, penso che gli strumenti di analisi statica che hanno incorporato in XCode non vorrebbero che si trovassero in un ramo separato. Piccolo dettaglio :-)

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

Credo che questo codice che aiuta,

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; 

E scrivere azione qui,

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