2009-07-03 17 views
12

Ich habe eine Symbolleiste mit verschiedenen Bild-Schaltflächen, in Interface Builder erstellt.Wie programmgesteuert ersetzt UIToolBar Elemente in IB

Ich möchte in der Lage sein, programmgesteuert eine der Schaltflächen durch einen Aktivitätsindikator zu ersetzen, wenn sie gedrückt wird, und dann die ursprüngliche Schaltfläche zurückzusetzen, aber die Farbe von Weiß nach Gelb zu ändern, wenn die Aktivität abgeschlossen ist.

Ist dies mit einer IB-integrierten Symbolleiste möglich oder muss ich beim Erstellen der gesamten Symbolleiste programmgesteuert und benutzerdefinierte Ansichten betrachten?

Antwort

26

Hier ist ein Beispiel dessen, was ich in einer ähnlichen Situation war. Ich wollte die Symbolleiste mit dem Interface Builder erstellen, aber eines der BarButtonItems abhängig davon, ob es "aktiviert" war oder nicht, umschalten. In diesem Beispiel sind einige wichtige Dinge zu beachten. Die folgenden zwei Membervariablen sind für die Klasse in der Header-Datei definiert:

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

Als ich das geprüften Status aktualisieren mag, nenne ich diese Funktion ... Bitte beachten Sie, dass es ein Selektor genannt definiert ist checkUncheckClicked, das ist aufgerufen, wenn auf die jeweilige Schaltfläche in der UIToolbar geklickt wird. Und die UIToolbar ist als IBOutlet zur Symbolleiste eingerichtet.Alternativ könnten Sie das UIBarButtonItem als Ausgang verbinden und es als Ihre Logik verwenden, um den Index der Schaltfläche zu identifizieren, oder Sie könnten den Index der Schaltfläche fest codieren, wenn sich die Dinge im Laufe der Zeit nicht ändern. Schließlich gibt es eine checked.png und unchecked.png, zwischen denen im Projekt enthalten ist.

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

Und natürlich sollten SymbolleisteItems und Symbolleiste in Ihrem Dealloc für die Klasse freigegeben werden.

Hoffe, das hilft!

1

Ich denke, es sollte möglich sein. Sie könnten entweder versuchen, ein IBOutlet für diese bestimmte Schaltfläche in Ihrer ViewController-Klasse zu erstellen, und die Schaltfläche von IB mit dieser Stelle verbinden, oder Sie können die items-Eigenschaft dieser UIToolbar-Instanz verwenden (Sie haben einen Verweis darauf, nicht wahr?) ?) und finde dort das passende Element, erstelle ein neues NSArray mit modifizierten Elementen und setze es auf die Eigenschaft toolbar.items zurück.

HTH

+0

sehr hilfreich, danke. Ich werde das ausprobieren und Sie wissen lassen, wie es geht. – frankodwyer

2

Hier ist der Ansatz, den ich verwenden Es schien viel einfacher zu sein, um die Symbolleiste programmatisch ganz so zu verwalten ....

Ihrer Ansicht Controller deklarieren 1 oder mehr Sätze von UIBarButtonItem Artikel als Eigenschaftenelemente deklarieren und verbinden die Symbolleiste auch als UIToolbar-Eigenschaft. Deklarieren Sie auch 1 oder mehrere Arrays, um die Elemente zu halten.

Bei der Umsetzung In viewDidLoad alloc und stellen Sie Ihre UIBarButtonItems zum Beispiel

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

Flexible Tasten (für die Ausrichtung usw.) sind wie diese erklärt

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

Es gibt mehrere initMethods die unterschiedlich zu behandeln Arten von Schaltflächen Symbolleisten unterstützen. Alle folgen einer ähnlichen Syntax wie oben. Bemerkenswert sind die Ziel- und Aktionseinstellungen. Target: wäre normalerweise self, action ist der Name der Funktion, die der Button auslösen soll.

Nachdem Sie Ihre UIBarButtons zugewiesen haben, fügen Sie sie mithilfe von initWithObjects zu einem Array hinzu.

dann die Schaltflächen auf der Symbolleiste zuweisen Sie

[toolbar setItems:<array name>]; 

Dont Ihre UIBarButtons und Arrays am Ende des Codes dealloc vergessen nennen würde.

Hoffe, das hilft. Wenn Sie mehr Code benötigen, lassen Sie es mich wissen.

Reiche D.

0

Ein Hinweis darauf - die Symbolleiste wird jede Farbe in Ihren Symbolen entfernen, so dass Sie es immer noch nicht gelb machen können. Sie müssen die Bildform ändern, um stattdessen "on" anzuzeigen.

Alternativ müssen Sie Ihre BarButtonItems mit UIButtons laden (verwenden Sie die initWithCustomView) und das Bild der Schaltfläche entsprechend einstellen.

HTH

0

Versuchen:

- (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 leckt, während Sie eine Kopie erstellen. Sie sollten es nach dem "tb.items = newItems" freigeben. rufen Sie auf, da die Symbolleiste es eigenständig behält. – Kalle

1

Swift

Vieles hat sich verändert seit haben diese Antworten gepostet. Hier ist eine Swift 2.0 Lösung.

Es spielt keine Rolle, wie das ursprüngliche UIBarButtonItem, das Sie ersetzen, programmgesteuert erstellt wurde. Alles, was Sie brauchen, ist die UIToolbar Steckdose. Um das zweite Element von links zu ersetzen, machen Sie folgendes:

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 hat einen viel einfacheren Weg. In meinem Fall wechsle ich die Play-Taste mit der Pause-Taste bei jeder Berührung.

@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

Gute Lösung! Obwohl der Schritt self.toolbar.setItems (toolbarItems, animated: true) fehlt und ich befürchte, dass es nicht funktionieren wird. –

0

Für die gesamte Symbolleiste, die Sie in IB erstellt (das heißt, zu sagen, nicht die einzelnen Elemente der Symbolleiste), erstellen Sie eine IBOutlet:

@IBOutlet weak var toolbarThatYouMade: UIToolbar! 

Dies ist eine Anordnung einzelner Elemente der Symbolleiste, so Sie würden das am weitesten links stehende Elemente (zum Beispiel) Zugriff mit einem [0] Index:

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

Dieser Code geht davon aus, dass Sie ein Bild haben in Ihrem Vermögen des Namen „New image“.

Sie können dann eine Bildänderung für einen Symbolleisteneintrag auslösen, ohne auf diesen bestimmten Eintrag zugreifen zu müssen. zum Beispiel, wenn Sie dies für so etwas wie ein Media-Player verwenden, könnten Sie Pause/Play-Bilder von schalten:
a) die Pause/Play-Taste selbst,
b) die Stopp-Taste,
c) wenn Sie sind benachrichtigt über eine Änderung des Player-Status,
oder
d) etwas anderes ganz. (Sei mutig! Sei mutig! Sei etwas anderes, das mit 'b' beginnt!)

+0

Danke für die Formatierung @ phiter-fernandes. (Ich hoffe ich habe das richtig gemacht.) – clyrinkpress

Verwandte Themen