2012-09-25 6 views
14

So come personalizzare UIBarButtonItem utilizzando -setBackgroundImage: forState: barMetrics:, ma mi piacerebbe utilizzare immagini diverse per UIBarButtonItemStyleDone e UIBarButtonItemStylePlain.Personalizzazione di UIBarButtonItem Stile "Fatto" e stile "Plain" separatamente utilizzando UIAppearance

C'è un modo per farlo usando il protocollo UIAppearance? O devo impostare l'immagine ogni volta che voglio un pulsante di stile "Fatto"?

(Ho provato a fare in giro con il codice come il seguente:

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

Ma che appena tramonta ogni pulsante della barra con l'immagine "Done".)

Grazie!

+0

Do u vuole cambiare l'immagine di nuovo in fare clic sul pulsante? – AppleDelegate

+0

Ho già personalizzato il pulsante Indietro. Sto cercando di avere diversi pulsanti "normali" (come il modo in cui iOS usa un pulsante blu per "Fatto" e "Salva", ma grigio per cose come "Annulla"). – James

+0

@James, Un'opzione consiste nell'utilizzare una sottoclasse personalizzata per il pulsante Fine come 'CustomDoneBarButtonItem' da' UIBarButtonItem' e usarlo come '[[CustomDoneBarButtonItem appearance] setBackgroundImage: image forState: UIControlStateNormal barMetrics: UIBarButtonItemStyleDone]'. Ogni volta che aggiungi un pulsante eseguito, crea un oggetto di questa classe personalizzata e aggiungilo. – iDev

risposta

13

In iOS 6 è possibile utilizzare il nuovo metodo di classe UIBarButtonItem:

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

Imposta immagine di sfondo per lo Stato, lo stile e metriche specificate. Maggiori dettagli sono disponibili in the Apple docs

Quindi, per modificare l'aspetto di tutte le UIBarButtonItems si può usare qualcosa di simile a:

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

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

il punto era quello di non doverlo manualmente –

+2

è l'API ufficiale, disponibile solo in iOS 6 (che ho dichiarato esplicitamente). Risolve esattamente il problema descritto: "modo di realizzare questo [diverse immagini per UIBarButtonItemStyleDone e UIBarButtonItemStylePlain] usando il protocollo UIAppearance". –

+0

sì, scusate il downvote non ha senso, ho letto male, totalmente mio cattivo! corretta. grazie per quello :) ho bisogno di ios5 anche se ... altrimenti sarebbe facile –

10

per IOS5 *

L'unico modo che ho trovato è usare una categoria 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 

Spero che questo sia stai cercando. credito per questa soluzione va a https://gist.github.com/2633081

+0

che funziona! un po 'hacker ma fico! –

+1

È questo [MethodSwizzling] (http://cocoadev.com/wiki/MethodSwizzling)? Se sì, c'è sempre il rischio di rifiuto dell'appstore. – iDev

+0

@acb si lo è, ma conosco molte app che lo fanno e mentre questo non lo rende in alcun modo legalizzato, mi sento male ** in questo caso ** –