Updating UIImage on UiBarButtonItem from identifier to image - ios

I am currently making an application for IOS but I am having trouble changing an image... what a shame...
The situation is like this :
I have a toolbar containing my items, and one of this items is the play button created from the identifier "Play". So I have my Play button without problem. Now I just want to change it to a pause image when I click on item and then switch again etc.
So I liked in my .h the item giving me :
#property (weak, nonatomic) IBOutlet UIBarButtonItem *play;
I tried many answers I found on this website and none of them did work on my case :/
The last one I tried was something like this :
UIButton *button1=[UIButton buttonWithType:UIButtonTypeCustom];
[button1 setFrame:CGRectMake(10.0, 2.0, 45.0, 40.0)];
[button1 addTarget:self action:#selector(showLeft:) forControlEvents:UIControlEventTouchUpInside];
[button1 setImage:[UIImage imageNamed:#"pause.png"] forState:UIControlStateNormal];
UIBarButtonItem *button = [[UIBarButtonItem alloc]initWithCustomView:button1];
self.play = button;
I also tried :
self.play.customView = button1;
But none of them really work, I can get the image by doing
self.view = button1;
But that only the picture (so the creation of the UIImage is okay) in the middle of the screen so....
(If you can also tell me how to go back to the play using identifier it would also be very helpful thanks a lot)
Thanks for your help.

If the button is already created and you have an outlet for it, you can simply set it like this:
UIImage* backgroundImage = [UIImage yourImage];
[self.barButtonItem setImage:backgroundImage];
Works like charm.

I think this should work.
-(IBAction)buttonClick:(UIBarButtonItem *)sender {
if ([[sender backgroundImageForState:UIControlStateNormal barMetrics:UIBarMetricsDefault] isEqual:[UIImage imageNamed:#"Play.jpg"]]) {
[sender setBackgroundImage:[UIImage imageNamed:#"Pause.jpg"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
}else{
[sender setBackgroundImage:[UIImage imageNamed:#"Play.jpg"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
}
}
Of course, you'll have to set the background image initially (in viewDidLoad) to the "Play" image for this to work.
After Edit:
If you want to use the system play and pause button, as far as I know, you have to replace the button. I don't think there's a way to just change the image. So, I did it this way. The button was set up in IB with the outlet playPauseButton, and the action playClick. I also made an outlet to the tool bar (toolBar).
-(IBAction)playClick:(UIBarButtonItem *)sender {
UIBarButtonItem *pause = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPause target:self action:#selector(pauseClick:)];
NSMutableArray *tbItems = [self.toolBar.items mutableCopy];
[tbItems removeObject:self.playPauseButton];
self.playPauseButton = pause;
[tbItems addObject:pause];
self.toolBar.items = tbItems;
}
-(void)pauseClick:(UIBarButtonItem *)sender {
UIBarButtonItem *play = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPlay target:self action:#selector(playClick:)];
NSMutableArray *tbItems = [self.toolBar.items mutableCopy];
[tbItems removeObject:self.playPauseButton];
self.playPauseButton = play;
[tbItems addObject:play];
self.toolBar.items = tbItems;
}

Create a custom button. Change the size of the button to match the image. Set image of the button. Add button view to UIBarButton play.
.h
IBOutlet UIBarButtonItem *play;
#property(nonatomic, retain) IBOutlet UIBarButtonItem *play;
.m
UIImage *image = [UIImage imageNamed:#"image.png"];
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeCustom];
button1.bounds = CGRectMake( 0, 0, image.size.width, image.size.height );
[button1 setImage:image forState:UIControlStateNormal];
play = [[UIBarButtonItem alloc] initWithCustomView:button1];
Make sure you connect your outlet for the UIBarButtonItem in Interface Builder.
Good luck!

The answer of rdelmar it's great. I would like to add an enhancement that avoid a flickering of the button because the remove and add of the button.
-(void)pauseClick:(UIBarButtonItem *)sender {
UIBarButtonItem *play = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPlay target:self action:#selector(playClick:)];
NSMutableArray *tbItems = [self.toolBar.items mutableCopy];
self.playPauseButton = play;
//instead of remove and add the new button, use the replaceObjectAtIndex method.
[tbItems replaceObjectAtIndex:2 withObject:play];
self.toolBar.items = tbItems;
}

You can try something like this for your custom button as one of the UIBarButtonItem.
- (void)viewDidLoad
{
// add our custom image button as the nav bar's custom right view
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"email.png"]
style:UIBarButtonItemStyleBordered target:self action:#selector(action:)];
self.navigationItem.rightBarButtonItem = addButton;
[addButton release];
}
- (IBAction)action:(id)sender
{
// the custom icon button was clicked, handle it here
// change image here
}

Related

How can I remove default button?

How can I remove dafult button to place my custom button in navbar? Problem at the moment is that my custom button is over default button.
Please take a look at the screenshot and it will be more clear.
I'm getting this with following code:
- (void)viewDidLoad
{
UIImage *menuImage = [UIImage imageNamed:#"barMenuButton.png"];
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithImage:menuImage style:UIBarButtonItemStylePlain target:self action:#selector(ShowLeftMenu:)];
[self.navigationItem setRightBarButtonItem:addButton];
}
This will fix your problem:
UIImage *menuImage = [UIImage imageNamed:#"barMenuButton.png"];
UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0, 0, 100, 40);
[button setImage:menuImage forState:UIControlStateNormal];
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithCustomView:button];
[addButton setAction:#selector(ShowLeftMenu:)];
[self.navigationItem setRightBarButtonItem:addButton];
You'll have to create a custom view and add that to the bar button item, as described in this article. This article also provides some details about creating custom UIButtons.

UIBarButtonItem not shown the same way in UIToolBar and UINavigationBar

I need to use a simple UIBarButtonItem in a UIToolBar.
I used this code to add the button with my custom image to the navigation bar:
UIBarButtonItem *cloneButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"image_sheep.png"] style:UIBarButtonItemStylePlain target:self action:#selector(clone)];
NSArray *rightItems = [NSArray arrayWithObject:cloneButton];
self.navigationItem.rightBarButtonItems = rightItems;
The result is what I want and it looks like this
navigation bar http://img207.imageshack.us/img207/3383/navigationbara.jpg
When doing the same thing in a UIToolBar that I'm adding to a UITableViewCell's contentView
UIBarButtonItem *cloneButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"image_sheep.png"] style:UIBarButtonItemStylePlain target:self action:#selector(clone)];
UIBarButtonItem *leftSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
toolbar.items = [NSArray arrayWithObjects:leftSpace, cloneButton, nil];
The problem is that I get something like this:
toolbar http://img209.imageshack.us/img209/1374/toolbary.jpg
This is surely due to the fact that UINavigationBar and UIToolBar are not drawn the same way...
Can someone please point out how to resolve this problem?
On your UIToolbar use UIBarButtonItemStyleBordered instead of UIBarButtonItemStylePlain.
UINavigationBar will not draw the button the same without the button look.
That's how UIToolbar is supposed to work. Per the documentation:
Toolbar images that represent normal and highlighted states of an item derive from the image you set using the inherited image property from the UIBarItem class. For example, the image is converted to white and then bevelled by adding a shadow for the normal state.
That said, you might be able to get the result you want by creating a UIBarButtonItem with a custom view instead of an image. Like so:
UIImage *sheepImage = [UIImage imageNamed:#"image_sheep.png"];
UIButton *sheepButton = [UIButton buttonWithType:UIButtonTypeCustom];
[sheepButton setImage:sheepImage forState:UIControlStateNormal];
[sheepButton addTarget:self action:#selector(clone) forControlEvents:UIControlEventTouchUpInside];
[sheepButton setShowsTouchWhenHighlighted:YES];
[sheepButton sizeToFit];
UIBarButtonItem *cloneButton = [[UIBarButtonItem alloc] initWithCustomView:sheepButton];
I haven't tested this, so I don't know if it will work.
I cannot see the images posted in the question anymore. But I am pretty sure that we're trying to mimic the UIBarButtonItemStylePlain of the UIToolBar in a UINavigationBar.
Benzado is pretty much spot on except for this line:
[sheepButton setImage:sheepImage forState:UIControlStateNormal];
This puts the image in front of the touch indicator. The UIToolBar shows the touch in front of the image. So to mimic the UIToolBar style in a UINavigationBar:
UIImage *sheepImage = [UIImage imageNamed:#"image_sheep.png"];
UIButton *sheepButton = [UIButton buttonWithType:UIButtonTypeCustom];
[sheepButton setBackgroundImage:sheepImage forState:UIControlStateNormal];
[sheepButton addTarget:self action:#selector(clone) forControlEvents:UIControlEventTouchUpInside];
[sheepButton setShowsTouchWhenHighlighted:YES];
[sheepButton sizeToFit];
UIBarButtonItem *cloneButton = [[UIBarButtonItem alloc] initWithCustomView:sheepButton];

Dismiss ModalView Programmatically by done button

I have to click on done button to dismiss modalview programmatically. I think UIButton is better than UIBarButtonItem to add UIControlEventsTouchupInside.
But with UIButton I'm confused what buttontype should use.
UIButton *button = [UIButton buttonWithType:UIButtonTypeInfoLight];
[button addTarget:self action:#selector(displayModalViewaction:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem * button = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:#selector(dismissViewaction:)] autorelease];
You will most likely want to use UIButtonTypeRoundedRect or UIButtonTypeCustom
With the custom type, you can add images for display.
You can try "stealing" these images from the UIBarButtonItem (image property defined in UIBarItem) and making the custom button look like the UIBarButtonSystemItemDone button
UIBarButtonItem * buttonForImage = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:nil action:nil] autorelease];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:#selector(displayModalViewaction:) forControlEvents:UIControlEventTouchUpInside];
[button setImage:buttonForImage.image forState:UIControlStateNormal];
Things to look out for. When setting an image for a UIButton, it does not scale to the size of the button according to contentMode property. If you want the image to follow the rules of the contentMode property, use setBackgroundImage: forState: instead.
I think the type of button doesn't matter. You have to assign an action or a selector to the button.
Something like this:
UIBarButtonItem *bttItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(yourBttAction:)] autorelease];
the action:
- (IBAction) yourBttAction:(id)sender
{
NSLog(#"Done Button clicked");
//do something
}
If the button is on the modalViewController, I usualy, for dismiss it, I use:
[self dismissModalViewControllerAnimated:(BOOL)];
or
//if you have a navigationController
[self.navigationController dismissModalViewControllerAnimated:(BOOL)];
But if you want to use a delegate to dismiss it, take a look at this tutorial

How to make leftBarButtonItem looking like backBarButtonItem?

The default solvings are not appropriate:
to change the previous ViewController title - I need to make my own function controlling the button touches up
to make a leftBarButtonItem and hide backBarButtonItem - leftBarButtonItem doesn't look like a default backBarButtonItem.
Here's an example to create a custom leftBarButtonItem:
UIImage *buttonImage = [UIImage imageNamed:#"backbutton.png"];
UIButton *aButton = [UIbutton buttonWithType:UIButtonTypeCustom];
[aButton setImage:buttonImage forState:UIControlStateNormal];
aButton.frame = CGRectMake(0.0,0.0,buttonImage.size.width,buttonImage.size.height);
[aButton addTarget:self action:#selector(aSelector) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithCustomView:aButton];
self.navigationItem.leftButtonItem = backButton;
Hope it helps...
Edit:
Try this...
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"yourimage.jpg"] style:UIBarButtonItemStyleBordered target:self action:#selector(aSelector)];
self.navigationItem.leftBarButtonItem = backButton;
I don't remember what type of button is the backbutton, try to change the default style to other. Good luck!
Just create a custom barbuttonitem and customize it with a picture similar to the back button item.
You can get its text from the view controllers in the navigation stack.
Then handle the taps to implement the desired effect
You can assign your custom views as the bar buttons to your navigation controller, like this:
UIBarButtonItem *customItem = [[UIBarButtonItem alloc] initWithCustomView:yourCustomizedControl];
[yourCustomizedControl release];
self.navigationItem.leftBarButtonItem = customItem;
[customItem release];
Check this Apple documentation for a more detailed explanation, if you want.
Here is a hack to add a back-like button:
UINavigationItem* backNavigationItem = [[UINavigationItem alloc] initWithTitle:#"Back"];
[_navigationBar pushNavigationItem:backNavigationItem animated:NO];
[backNavigationItem release];
You can add more items (such like title, right button) this way:
UINavigationItem *navigationItem = [[UINavigationItem alloc] initWithTitle:#"Title"];
navigationItem.rightBarButtonItem = // Some UIBarButtonItem
[_navigationBar pushNavigationItem:navigationItem animated:NO];
[navigationItem release];

UIButton not showing in iOS

Following is a code to display a button to the toolbar.
UIButton myButton = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *myImage = [UIImage imageNamed:#"img1.png"];
[myButton setBackgroundImage:myImage forState:UIControlStateNormal];
UIBarButtonItem *myToolbarButton = [[UIBarButtonItem alloc] initWithCustomView:myButton];
Nothing gets displayed on the toolbar. Please tell me what is wrong.
[myToolbar setItems:[NSArray arrayWithObject:myToolbarButton]]; // might help
OR if it's a navigation bar
self.navigationItem.rightBarButtonItem = myToolbarButton;
Also you should set the frame for the custom button, something like this:
UIButton *mybutton = [[UIButton alloc] initWithFrame:CGRectMake:0,0,200,50];
Then if you want to add a selector/callback:
[myButton addTarget:self action:#selector(someMethod) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.leftBarButtonItem = myButtonItem; // and change for the right button.
Where self is a UIViewController.
You forgot to add this button to the toolbar!
NSArray *toolbarItems = [[NSArray alloc] initWithObjects:myToolbarButton,nil]; // you can more buttons here
[aToolbar setItems:toolbarItems animated:NO]; // change to YES if you want to have nice animation
[toolbarItems release];
If you want to add a button to navigation bar, use this:
[self.navigationItem setRightBarButtonItem:myToolbarButton]; // or setLeft...
Also, you should remember to set the frame of myButton:
[myButton setFrame:CGRectMake(0, 0, 30, 32)];

Resources