2009-07-03 6 views
12

Ho una barra degli strumenti con vari pulsanti immagine, creati in Interface Builder.Come sostituire a livello di codice oggetti UIToolBar costruiti in IB

Mi piacerebbe essere in grado di sostituire a livello di programmazione uno dei pulsanti con un indicatore di attività quando viene premuto, quindi ripristinare il pulsante originale ma cambiarne il colore da bianco a giallo al termine dell'attività.

Ciò è possibile con una barra degli strumenti IB costruita o devo cercare di costruire l'intera barra degli strumenti a livello di programmazione e visualizzazioni personalizzate?

risposta

26

Ecco un esempio di quello che ho fatto in una situazione simile. Volevo costruire la barra degli strumenti utilizzando Interface Builder ma attivare uno dei BarButtonItem in base al fatto che fosse "controllato". In questo esempio, ci sono alcune cose chiave da notare. I seguenti 2 variabili membro sono definite per la classe nel file di intestazione:

NSMutableArray *toolbarItems; 
IBOutlet UIToolbar *toolbar; 
NSUInteger checkUncheckIndex; 

Quando voglio aggiornare lo stato controllato, io chiamo questa funzione ... Si prega di notare che v'è un selettore definito chiamato checkUncheckClicked che è chiamato quando si fa clic sul particolare pulsante nella UIToolbar. E la barra degli strumenti UIT è configurata come barra degli strumenti IBOutlet.In alternativa, è possibile collegare UIBarButtonItem come una presa e utilizzarla come logica per identificare l'indice del pulsante o, in caso contrario, è possibile codificare l'indice del pulsante nel caso in cui le cose non cambino nel tempo. Infine, c'è un check.png e unchecked.png da alternare tra quelli inclusi nel progetto.

- (void)updateBarButtonItemChecked:(BOOL)checked { 
    if (toolbarItems == nil) { 
     toolbarItems = [[NSMutableArray arrayWithArray:toolbar.items] retain]; 
     checkUncheckIndex = -1; 

     for (NSUInteger i = 0; i < [toolbarItems count]; i++) { 
      UIBarButtonItem *barButtonItem = [toolbarItems objectAtIndex:i]; 
      if (barButtonItem.action == @selector(checkUncheckClicked)) { 
       favoriteIndex = i; 
       break; 
      } 
     } 
    } 

    if (checkUncheckIndex != -1) { 
     UIBarButtonItem *barButtonItem = [[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:checked ? @"checked.png" : @"unchecked.png"] 
                      style:UIBarButtonItemStylePlain target:self action:@selector(checkUncheckClicked)] autorelease]; 
     [toolbarItems replaceObjectAtIndex:checkUncheckIndex withObject:barButtonItem]; 

     toolbar.items = toolbarItems; 
    } 
} 

E, naturalmente, gli strumenti e la barra degli strumenti devono essere rilasciati nel dealloc per la classe.

Spero che questo aiuti!

1

Penso che dovrebbe essere possibile. Potresti provare a creare un IBOutlet per quel pulsante specifico nella tua classe ViewController e connettere il pulsante da IB a quel punto vendita, oppure puoi usare la proprietà items di quell'istanza di UIToolbar (hai un riferimento a questo, non è vero? ?) e trovare l'elemento appropriato in là, creare un nuovo NSArray con elementi modificati e reimpostarlo sulla proprietà toolbar.items.

HTH

+0

molto utile, grazie. Ci proverò e ti farò sapere come va. – frankodwyer

2

Qui è l'approccio che ho usato Sembrava di essere molto più semplice da gestire la barra degli strumenti del tutto programatically così ....

Nel vostro controller della vista dichiarano 1 o più insiemi di oggetti UIBarButtonItem come anche le voci di proprietà dichiarano e collegano la barra degli strumenti come una proprietà UIToolbar. Dichiarare anche 1 o più matrici per contenere gli oggetti.

Nell'implementazione In viewDidLoad alloc e impostare le UIBarButtonItems per esempio

pulsanti
 playButton = [[UIBarButtonItem alloc] 
     initWithBarButtonSystemItem:UIBarButtonSystemItemPlay 
    target:self 
action:@selector(handlePlayClick)]; 

flessibili (per l'allineamento ecc) che sono dichiarati come questo

flexButton1 =[[UIBarButtonItem alloc] 
initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace 
target:nil action:nil]; 

Ci sono diversi initMethods per gestire il diverso tipi di pulsanti barre degli strumenti di supporto. Tutti seguono una sintassi simile a quella sopra. Degno di nota è il bersaglio e le impostazioni di azione. Target: dovrebbe essere di per sé, l'azione è il nome della funzione che il pulsante dovrebbe attivare.

Dopo l'allocazione dei pulsanti UIBar, aggiungerli a un array utilizzando initWithObjects.

Poi per assegnare i pulsanti alla barra degli strumenti che definireste

[toolbar setItems:<array name>]; 

Non dimenticate di dealloc tuoi UIBarButtons e array alla fine del codice.

Spero che questo aiuti. Se hai bisogno di più codice fammi sapere.

Rich D.

0

Una nota a questo proposito: la barra degli strumenti cancella qualsiasi colore nelle icone, quindi non sarà ancora possibile renderlo giallo. Avrai bisogno di cambiare la forma dell'immagine per indicare "on" invece.

In alternativa è necessario caricare i BarButtonItems con UIButtons (utilizzare initWithCustomView) e impostare l'immagine del pulsante in modo appropriato.

HTH

0

Prova:

- (void)setTitle:(NSString *)title forItem:(int)item ofToolbar:(UIToolbar *)tb { 
    NSMutableArray *newItems = [tb.items mutableCopy]; 
    UIBarButtonItem *old = [newItems objectAtIndex:1], 
    *titled = [[UIBarButtonItem alloc] initWithTitle:title style:old.style target:old.target action:old.action]; 

    [newItems replaceObjectAtIndex:1 withObject:titled]; 
    tb.items = newItems; 

    [titled release]; 
} 
+1

newItems perde mentre si sta facendo una copia. Dovresti rilasciarlo dopo "tb.items = newItems"; chiamata, poiché la barra degli strumenti la manterrà autonoma. – Kalle

1

Swift

Molto è cambiato da queste risposte sono state pubblicate. Ecco una soluzione Swift 2.0.

Non importa come è stato creato l'originale UIBarButtonItem che si sta sostituendo. Tutto ciò che serve è la presa UIToolbar. Per sostituire, ad esempio, il 2 ° oggetto da sinistra, procedere come segue:

var toolbarItems = self.toolbar.items 
let newItem = UIBarButtonItem(barButtonSystemItem: .Play, target: self, action: "play") 
toolbarItems![1] = newItem 
self.toolbar.setItems(toolbarItems, animated: true) 
2

Swift ha un modo molto più semplice. Nel mio caso, sto cambiando il pulsante di riproduzione con il pulsante di pausa ogni volta.

@IBAction func playandPause(sender: UIBarButtonItem) { // Here we are creating an outlet. Hook this up to the bar button item. 
    for (index, button) in toolbarItems!.enumerate() { // Enumerating through all the buttons 
     if button === sender { // === operator is used to check if the two objects are the exact same instance in memory. 
      var barButtonItem: UIBarButtonItem! 
      if mediaplayer.playing { 
       mediaplayer.pause() 
       barButtonItem = UIBarButtonItem.init(barButtonSystemItem: .Play, target: self, action: #selector(playandPause(_:))) 
      }else { 
       mediaplayer.play() 
       barButtonItem = UIBarButtonItem.init(barButtonSystemItem: .Pause, target: self, action: #selector(playandPause(_:))) 
      } 
      toolbarItems![index] = barButtonItem // Replace the old item with the new item. 
      break // Break once we have found the button as it is unnecessary to complete the rest of the loop 
     } 
    } 
} 
+0

Buona soluzione! Sebbene manchi il passo self.toolbar.setItems (toolbarItems, animated: true) e senza di esso temo che non funzioni. –

0

Per l'intera barra degli strumenti che si è creato in IB (vale a dire, non i singoli elementi della barra degli strumenti), creare un IBOutlet:

@IBOutlet weak var toolbarThatYouMade: UIToolbar! 

Questo è un array di singoli elementi della barra degli strumenti, in modo da si dovrebbe accedere al membro più a sinistra (per esempio) con un indice di [0]:

toolbarThatYouMade.items![0].image = UIImage(named: "New Image") 

Questo codice presuppone che si è un'immagine denominata "Nuova immagine" nel vostro patrimonio.

È quindi possibile attivare una modifica dell'immagine per un elemento della barra degli strumenti senza dover accedere a quell'elemento specifico stesso; per esempio, se si sta utilizzando questo per qualcosa di simile a un lettore multimediale, è possibile attivare o disattivare le immagini di pausa/riprodurre da:
a) il pulsante/Pause Play per sé,
b) il pulsante Stop,
c) quando si è notifica di un cambio di stato giocatore,
o
d) qualcos'altro interamente. (Sii coraggioso, sii audace! Sii qualcos'altro che inizia con "b"!)

+0

Grazie per la formattazione @ phiter-fernandes. (Spero di averlo fatto correttamente). – clyrinkpress