Updating UIImage on UiBarButtonItem from identifier to image

17,206

Solution 1

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

Solution 2

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.

Solution 3

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;
}
Share:
17,206
Clad Clad
Author by

Clad Clad

Mobile dev :3

Updated on July 22, 2022

Comments

  • Clad Clad
    Clad Clad almost 2 years

    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.

  • Clad Clad
    Clad Clad almost 11 years
    My actual problem is that I wanted to use the play from ios by using the identifier "play" in xcode interface. We are getting closer because I can change the backgroundImage with your method but why doesn't it work in the same way when I do the same but changing the picture? There are no way to update directly the image ?
  • Clad Clad
    Clad Clad almost 11 years
    I can't used this because my item in not in the navigation bar but in a toolbar in the middle of the screen.
  • Clad Clad
    Clad Clad almost 11 years
    I just checked for identifier changing but same results. creating : [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemPause target:self action:@selector(pushPlay:)]; and same for the play one then in my code setting self.play = pauseIco but it does nothing.
  • Clad Clad
    Clad Clad almost 11 years
    I finally succed to make it works by putting only my own images, so without using identifier, but if you know a way to do it with the identifier I would be grateful to you. Thanks a lot.
  • rdelmar
    rdelmar over 10 years
    @CladClad I updated my answer to show how I did it using the system buttons.
  • Clad Clad
    Clad Clad over 10 years
    Finally I used 2 images and no identifiers for the moment but thanks for your help :)