user6631314
user6631314

Reputation: 1960

IOS/Objective-C: Assign custom image to UIBarButtonItem

I am able to assign some images to a UIBarButton item--simple line icons easily in InterfaceBuilder. However, when I assign a full color image, it makes the entire image the color of the tint, blue for default value. If I set the tint to clear color the image disappears. I can't get it to show the image.

I know it is possible to show an image by creating an UIImageView, making a button and assigning the UIImageView to the button, but it seems strange that you have to go to all this trouble for some images, when other images display correctly by just assigning the image property in IB.

Does anyone know of a way to display a colored image without having to go through the whole rigamarole of creating a view etc.

something like btnItem.image = @"myimage.png";

Long way I would like to avoid...

UIImageView* v = [[UIImageView alloc] initWithFrame:CGRectMake(4, 0, 36, 36)];

UIImage *myImage = [UIImage imageNamed:@"headshot-32.png"];  

v.image =myImage;
UIImage *scaledImage = [UIImage imageWithCGImage:[myImage CGImage] scale:(35) orientation:(myImage.imageOrientation)];
v.image=scaledImage;
v.layer.cornerRadius = v.frame.size.width / 2;
v.contentMode = UIViewContentModeScaleAspectFill;
v.clipsToBounds = YES;

UIBarButtonItem* roundBtn = [[UIBarButtonItem alloc] initWithCustomView:v];
self.navigationItem.leftBarButtonItems = @[roundBtn];

Upvotes: 0

Views: 665

Answers (3)

Nayab Muhammad
Nayab Muhammad

Reputation: 90

Alright do one thing make UIBarButtonItem programmatically in viewWillAppear

UIButton *ArrowSnapCapture  = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 40 , 35)];
[ArrowSnapCapture setImage:[UIImage imageNamed:@"ArrowIcon"] forState:UIControlStateNormal];
[ArrowSnapCapture addTarget:self action:@selector(CaptureSS) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:Notification];
[self.navigationItem setRightBarButtonItem:rightBarButtonItem];

rightBarButtonItem=nil;

Upvotes: -1

mag_zbc
mag_zbc

Reputation: 6982

The problem is rendering mode. When creating an instance of UIImage, its renderingMode property has a default value of UIImageRenderingModeAutomatic. Now, from the documentation of this rendering mode:

Use the default rendering mode for the context where the image is used.

For a UIBarButtonItem rendering mode defaults to UIImageRenderingModeAlwaysTemplate, which creates actually displayed image based on source image's alpha channel.

What you want to do is to change your image's rendering mode to UIImageRenderingModeAlwaysOriginal

UIImage *scaledImage = [UIImage imageWithCGImage:[myImage CGImage] scale:(35) orientation:(myImage.imageOrientation)];
scaledImage.renderingMode = UIImageRenderingModeAlwaysOriginal;
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithImage:scaledImage
                                           style:UIBarButtonItemStylePlain
                                           target:yourTarget
                                           action:someSelector];

This ensures that an original image will be displayed, instead of one created from alpha channel.

Upvotes: 2

Pablo Marrufo
Pablo Marrufo

Reputation: 885

I would do something like this:

 UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom];
 [b setFrame:CGRectMake(0, 0, 36, 36)];
 [b addTarget:self action:@selector(randomMsg) forControlEvents:UIControlEventTouchUpInside];
 [b setImage:[UIImage imageNamed:@"headshot-32.png"] forState:UIControlStateNormal];
 UIBarButtonItem * roundBtn = [[UIBarButtonItem alloc] initWithCustomView:b];
 self.navigationItem.leftBarButtonItems = @[roundBtn];

Upvotes: 2

Related Questions