2

We have added UIBarButtonItem using storyboard and at runtime on click we wanted to change its image ( functionality similar to add bookmark /remove bookmark).

Researched on stack overflow.. lot of folks recommended using UIButton inside UIBarbuttonItem.

Below code changes image but its stretched ( even original image is showing as stretched.

Can anyone guide us for changing image only using UIBarButton ( not using UIButton )?

 [_barButtonAddToFav setBackgroundImage:[UIImage imageNamed:@"ic_add_to_fav.png"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
HRM
  • 2,097
  • 6
  • 23
  • 37
Amod Gokhale
  • 2,346
  • 4
  • 17
  • 32

5 Answers5

4

UIBarButtonItem will stretch whole image to its bar button area.

To solve this problem, Drag an UIButton inside your UIBarButtonItem and set image on UIButton.

Set UIButton type as custom and all property as want to set for BarButton.

It not get stretched and also you'll be able to set width/height resolution same as your image have.

Hope its help. Please let me know if we have to go with another solution.

  • Thanks .. Went with this approach! – Amod Gokhale Feb 21 '14 at 14:13
  • Tried the other ways because I *really* wanted to do it programmatically, but none of the solutions I found here or other places worked. I had to use this method and set the size of the `UIButton`. – dstudeba Nov 07 '15 at 00:16
2

I was struggling with this recently, all the solutions seem convoluted but it turns out that this just works (at least if the original image allocated on the storyboard is the same size as the new image - not sure it would if they differ):

barButton.image = (UIImage(named: "NewImage"))
Ali Beadle
  • 4,486
  • 3
  • 30
  • 55
1

Dont use :setBackgroundImage for UIBarButtonItem, rather Initialise it with following syntax of initialization with Image

This will simply create button with image, that will never Stretched.

   self.navigationItem.hidesBackButton = true
   let backButton = UIBarButtonItem(image: UIImage(named: "ico-nav-prev"), style: .Plain, target: self, action: #selector(viewController.back(_:)))
   self.navigationItem.leftBarButtonItem = backButton
ViJay Avhad
  • 2,684
  • 22
  • 26
0

Amod you can try this coding.It will help you anyway.

UIImage *buttonImg = [UIImage imageNamed:@"myImg.png"];
UIImage *buttonGreyImg = [buttonImg stretchableImageWithLeftCapWidth:12 topCapHeight:0];
[myButton setBackgroundImage:buttonGreyImg forState:UIControlStateNormal];
user3182143
  • 9,459
  • 3
  • 32
  • 39
0

Also the another code(ANSWER) for your QUESTION

 // Change the appearance of back button
     UIImage *backButtonImage = [[UIImage imageNamed:@"button_back"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 13, 0, 6)];
     [[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

 // Change the appearance of other navigation button
     UIImage *barButtonImage = [[UIImage imageNamed:@"button_normal"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 6, 0, 6)];
     [[UIBarButtonItem appearance] setBackgroundImage:barButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
user3182143
  • 9,459
  • 3
  • 32
  • 39