views:

5360

answers:

5

I have a toolbar with various image buttons, created in Interface Builder.

I'd like to be able to programmatically replace one of the buttons with an activity indicator when pressed, and then put back the original button but change its color from white to yellow when the activity completes.

Is this possible with an IB built toolbar or must I look at building the whole toolbar programmatically and custom views?

+1  A: 

I think it should be possible. You might either try creating an IBOutlet for that specific button in your ViewController class, and connect the button from IB to that outlet, or you can use the items property of that UIToolbar instance (you do have a reference to that, don't you?) and find the appropriate item in there, create a new NSArray with modified items, and set it back on that toolbar.items property.

HTH

drvdijk
very helpful, thanks. I will try this out and let you know how it goes.
frankodwyer
A: 

Here is the approach I used It seemed to be much simpler to manage the toolbar entirely programatically so ....

In your view controller declare 1 or more sets of UIBarButtonItem items as property items also declare and hookup the toolbar as a UIToolbar property. Also declare 1 or more arrays to hold the items.

In the implementation In viewDidLoad alloc and set your UIBarButtonItems for example

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

Flexible buttons (for alignment etc) are declared like this flexButton1 =[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];

There are several initMethods to handle the different types of buttons toolbars support. All follow a syntax similar to the above. Worth noting is the target and action settings. Target: would normally be self, action is the name of the function that button should trigger.

After alloc'ng your UIBarButtons add them to an array using initWithObjects.

Then to assign the buttons to the toolbar you would call [toolbar setItems:];

Dont forget to dealloc your UIBarButtons and arrays at the end of your code.

Hope this helps. If you need more code let me know.

Rich D.

Rich Dominelli
+4  A: 

Here is an example of what I did in a similar situation. I wanted to build the toolbar using Interface Builder but toggle one of the BarButtonItems based on whether or not it was "checked". In this example, there are a few key things to note. The following 2 member variables are defined for the class in the header file:

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

When I want to update the checked status, I call this function... Please note that there is a selector defined called checkUncheckClicked that is called when the particular button in the UIToolbar is clicked. And the UIToolbar is set up as an IBOutlet to toolbar. Alternately, you could hook up the UIBarButtonItem as an outlet itself and use that as your logic to identify the index of the button, or for that matter, you could hard-code the index of the button if things won't change over time. Finally, there is a checked.png and unchecked.png to alternate between that is included in the project.

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

And, of course toolbarItems and toolbar should be released in your dealloc for the class.

Hope this helps!

Aaron
A: 

A note on this - the toolbar will strip out any color in your icons, so you still won't be able to make it yellow. You'll need to change the image shape to indicate "on" instead.

Alternatively you'll need to load your BarButtonItems with UIButtons (use the initWithCustomView) and set the image of the button appropriately.

HTH

theLastNightTrain
A: 
 Try:

   - (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];
    }
Wanderer
newItems leaks as you're making a copy. You should release it after the "tb.items = newItems;" call, as the toolbar will retain it on its own.
Kalle