2009-02-11 17 views
8

Tengo una aplicación NavigationBar con dos vistas: una principal y una subvista. En la vista de sub estoy añadiendo un botón a la esquina derecha de la siguiente manera:Cómo cambiar la imagen y desactivar 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]; 
} 

Cuando se hace clic en el botón que quiero cambiar la imagen de este rightBarButtonItem y desactivar la leftBarButtonItem (que se añadió de forma automática por el controlador) Básicamente tiene dos estados de un botón, bloqueado y desbloqueado.

Pregunta 1: La única forma en que puedo encontrar cómo cambiar la imagen es crear un nuevo UIButtonItem con una nueva imagen y reemplazar rightBarButtonItem con la nueva. Pero me pregunto si hay una manera de simplemente cambiar la imagen sin crear un nuevo UIBarButtonItem. ¿Estoy creando una pérdida de memoria si sigo creando un nuevo UIBarButtonItem?

Pregunta 2: ¿Cómo puedo obtener una autorización de self.navigationItem.leftBarButtonItem y desactivarla/habilitarla? No lo creo manualmente, el controlador lo crea automáticamente para mí. No veo ningún método/propiedad en UIBarButtonItem para habilitar/deshabilitar la interacción del usuario con él.

Respuesta

18

Pregunta 1: Declarar UIBarButtonItem * tempButton en la interfaz

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

@property (nonatomic, retain) UIBarButtonItem *tempButton; 

y sintetizarla en la implementación.

@synthesize tempButton; 

Crea el objeto en viewDidLoad similar a como eres ahora.

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

Pero no lo suelte aquí, libérelo en el método dealloc que normalmente se encuentra en la parte inferior.

Luego, cuando LOCKSCREEN se llama hacer

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

no tengo una respuesta para la pregunta 2, im miedo!

+1

Este enfoque se ve mucho mejor. ¡Gracias! –

+3

Un pequeño problema para la tercera parte del código: PUEDE liberar tempButton después de alloc porque ya se ha conservado cuando lo declara como una propiedad. –

+0

en realidad iPhoney. porque no llamó a self.tempButton, la propiedad NO retendrá. retener propiedad solo se puede activar si usa self.VAR –

7

En lo que se refiere a la pregunta 2, utilice la propiedad 'permitido':

self.navigationItem.leftBarButtonItem.enabled = NO; 
5

No puedo entender si tiene un navigationController, pero en este caso para desactivar el botón de retroceso es necesario llamar a:

self.navigationItem.hidesBackButton = YES; 
+0

¿No ocultará esto en lugar de desactivar el botón? –

0

yo no era capaz de desactivar/grises a un botón de barra de navegación con:

self.navigationItem.leftBarButtonItem.enabled = NO; 

... pero ocultando la el botón Atrás funciona bien!

self.navigationItem.hidesBackButton = YES; 

Gracias Dzamir!

0

El uso de "hidesBackButton = YES" no es realmente una solución elegante, ya que oculta el botón que no es lo que queremos. Una solución aceptable sería agregar un UILabel a la ventana justo sobre el botón Atrás, al menos desactivando los toques en el botón.

Añadir este método a la clase 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; 
    } 
} 

Se le puede llamar así desde cualquier controlador de vista para desactivar:

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

Para habilitar:

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

no deben ¿Lo anterior ha liberado el UILabel * l después de la llamada [self.window addSubView: l]? De esta forma, se conserva +1 cuando se agrega a la Subvista, pero se libera -1 en la misma rama. De lo contrario, debe llamar a disableLeftBarButtonItemOnNavbar: NO para liberarlo. Y mientras, terminarás en el mismo lugar al final, no estás goteando, creo que a las herramientas de análisis estático que han incorporado a XCode no les gustaría que estuvieran en una rama separada. Pequeño detalle :-)

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

Creo que este código le ayuda,

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; 

Y escribir acción aquí,

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