2012-09-25 16 views
14

Sé cómo personalizar UIBarButtonItem usando -setBackgroundImage: forState: barMetrics:, pero me gustaría usar diferentes imágenes para UIBarButtonItemStyleDone y UIBarButtonItemStylePlain.Personalizar el estilo UIBarButtonItem "Hecho" y el estilo "Normal" por separado usando UIAppearance

¿Hay alguna manera de lograr esto usando el protocolo UIAppearance? ¿O tengo que configurar la imagen cada vez que quiero un botón de estilo "Hecho"?

(He intentado jugar un poco con código como el siguiente:

[[UIBarButtonItem appearance] setBackgroundImage:image forState:UIControlStateNormal barMetrics:UIBarButtonItemStyleDone];

Pero eso simplemente se pone cada botón de la barra con la imagen "Hecho".)

Gracias!

+0

Do u quieren cambiar la imagen de nuevo en el botón de clic? – AppleDelegate

+0

Ya he personalizado el botón Atrás. Estoy buscando tener diferentes botones de barra "normales" (por ejemplo, cómo iOS usa un botón azul para "Hecho" y "Guardar", pero gris para cosas como "Cancelar"). – James

+0

@James, Una opción es usar una subclase personalizada para el botón Hecho como 'CustomDoneBarButtonItem' de' UIBarButtonItem' y usarla como '[[CustomDoneBarButtonItem aparición] setBackgroundImage: image forState: UIControlStateNormal barMetrics: UIBarButtonItemStyleDone]'. Cada vez que agregue un botón hecho, cree un objeto de esta clase personalizada y agréguelo. – iDev

Respuesta

13

En iOS 6 puede utilizar el nuevo método de clase UIBarButtonItem:

- (void)setBackgroundImage:(UIImage *)backgroundImage 
        forState:(UIControlState)state 
        style:(UIBarButtonItemStyle)style 
       barMetrics:(UIBarMetrics)barMetrics 

Establece la imagen de fondo para el estado, el estilo y las métricas especificadas. Más detalles están disponibles in the Apple docs

lo que para cambiar el aspecto de todas UIBarButtonItems se puede usar algo como:

UIImage *doneBackgroundImage = [[UIImage imageNamed:@"button_done.png"] 
    resizableImageWithCapInsets:UIEdgeInsetsMake(0, 4, 0, 4)]; 

[[UIBarButtonItem appearance] setBackgroundImage:doneBackgroundImage 
              forState:UIControlStateNormal 
               style:UIBarButtonItemStyleDone 
              barMetrics:UIBarMetricsDefault]; 
+0

el punto era no tener que hacerlo manualmente –

+2

es una API oficial, disponible solo en iOS 6 (que dije explícitamente). Resuelve exactamente el problema descrito: "forma de lograr esto [diferentes imágenes para UIBarButtonItemStyleDone y UIBarButtonItemStylePlain] usando el protocolo UIAppearance". –

+0

Sí, lo siento, el perdón no tiene sentido, lo leyó mal, ¡totalmente mal! correcto. gracias por eso :) necesito ios5 sin embargo ... de lo contrario sería fácil –

10

para iOS5 *

La única manera que he encontrado es el uso de una categoría UIBarButtonItem:

UIBarButtonItem + Appearance.h

#import <Foundation/Foundation.h> 

@interface UIBarButtonItem (Appearance) 

+ (void) setupAppearance; 

@end 

UIBarButtonItem + Appearance.m

#import "UIBarButtonItem+Appearance.h" 
#import <objc/runtime.h> 

@implementation UIBarButtonItem (Appearance) 

+ (void) setupAppearance { 
    [[UIBarButtonItem appearance] setBackgroundImage: [[UIImage imageNamed:@"customButton"] 
                    resizableImageWithCapInsets: UIEdgeInsetsMake(8, 8, 8, 8)] 
                 forState: UIControlStateNormal 
                barMetrics: UIBarMetricsDefault]; 

    [[UIBarButtonItem appearance] setBackgroundImage: [[UIImage imageNamed:@"customButtonHiglhighted"] 
                    resizableImageWithCapInsets: UIEdgeInsetsMake(8, 8, 8, 8)] 
                 forState: UIControlStateHighlighted 
                barMetrics: UIBarMetricsDefault]; 



    Class klass = objc_getClass("UIBarButtonItem"); 
    Method targetMethod = class_getInstanceMethod(klass, @selector(setStyle:)); 
    Method newMethod = class_getInstanceMethod(klass, @selector(__setStyle:)); 
    method_exchangeImplementations(targetMethod, newMethod); 
} 

- (void) __setStyle:(UIBarButtonItemStyle)style { 
    [self __setStyle:style]; 

    if(style == UIBarButtonItemStyleDone) { 
     [self setBackgroundImage:[[UIImage imageNamed:@"customDoneButton"] resizableImageWithCapInsets: UIEdgeInsetsMake(8, 8, 8, 8)] 
         forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 
     [self setBackgroundImage:[UIImage imageNamed:@"customDoneButtonClicked"] 
         forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault]; 
    } else { 
     [self setBackgroundImage:[[UIImage imageNamed:@"customButton"] resizableImageWithCapInsets: UIEdgeInsetsMake(8, 8, 8, 8)] 
         forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 
     [self setBackgroundImage:[UIImage imageNamed:@"customButtonHighlighted"] 
         forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault]; 
    } 
} 

@end 

Espero que esto sea Estás buscando. crédito para esta solución va a https://gist.github.com/2633081

+0

que funciona! un poco hackish pero genial! –

+1

¿Es esto [MethodSwizzling] (http://cocoadev.com/wiki/MethodSwizzling)? Si es así, siempre existe el riesgo de rechazo de la tienda de aplicaciones. – iDev

+0

@acb sí lo es, pero sé que hay muchas aplicaciones que lo hacen y aunque esto no legaliza esto en absoluto, me siento bien ** en este caso ** –

Cuestiones relacionadas