setting image for UIBarButtonItem - image stretche

2019-01-11 21:58发布

When I try to use UIBarButtonItem's "initWithImage" to initialize a navigation bar custom image, it comes out washed-up and stretched against a black navigation bar. This is how I create it:

UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"gear.png"] style:UIBarButtonItemStyleBordered target:self action:@selector(showSetting:)];

Here is what it looks like:

enter image description here

Any idea if it's a problem with the image? I got it from a set of icons I bought.

6条回答
趁早两清
2楼-- · 2019-01-11 22:41

The displayed images on bar button items are 'derived' from the source image (it uses only the alpha channel values in rendering but that all looks ok in your image). Its possibly just not the right size - you might need to open the image file and crop it to the right size.

You could also try looking at whether setting the imageInsets property (inherited by UIBarButtonItem from UIBarItem) can be used to adjust the size in a way to stop it getting stretched.

Doco on the bar item images says the following:

The images displayed on the bar are derived from this image. If this image is too large to fit on the bar, it is scaled to fit. Typically, the size of a toolbar and navigation bar image is 20 x 20 points.

查看更多
疯言疯语
3楼-- · 2019-01-11 22:42

stretch

I got the same stretched issue for my 40x40 image when I set the background image for leftBarButtonItem

UIBarButtonItem *backButton = [UIBarButtonItem new];
[backButton setBackButtonBackgroundImage:[UIImage imageNamed:@"back_icon"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

self.navigationItem.leftBarButtonItem = backButton;

But my issue got resolved with the following code

resolved

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back_icon"] style:UIBarButtonItemStylePlain target:self action:@selector(handleBack:)];

self.navigationItem.leftBarButtonItem = backButton;

and same result if UIBarButtonItemStyleBordered is used.

查看更多
贼婆χ
4楼-- · 2019-01-11 22:43

I know this question already has a checkmarked anser. But I ran in to this today and thought I would offer up my answer anyway. The check marked answer above did help me, but it also took some extra experimenting to figure out what was really happening.

The button image is being shrunk only in the x axis and not the y. this is because it is too tall for the button and it shrinks it down to fit. But it doesn't shrink it proportionally. Only on the vertical. So it appears stretched. It's not actually stretched - which implies a widening of it. Instead the height is shrunk. Knowing the difference I think is important to understanding why it's happening and how to fix it.

enter image description here

I did the same thing the OP did. Thinking that I am supporting retina I made my icon 40x40. Mine was a green checkmark with an alpha channel. It was padded with blank pixels to be 40x40. The app resized it to fit within the button's available height. But the width stayed the same. So it became somewhere in the range of 40x30 or 40x20. I think the button can handle an icon 30 high, but then it's a little too big for the box IMHO.

The OP reduced the button to 30x30 and that made it not squish any more. But that's not the best solution. Because it isn't actually a retina button when you do that. It's shrunk and then blown back up on the retina.

The correct answer is to name your 40 pixel tall version with the @2x and then make a half size (20 pixel tall) version and save it without the @2x. The width can be whatever. Then load with imageNamed: without specifying the @2x. It will use the appropriate png for a retina or non-retina device.

The next thing that happened to me was then the button frame was too small. So I upped my canvas size in psd to pad the png to 80 wide to make the button slightly wider and more tappable.

查看更多
戒情不戒烟
5楼-- · 2019-01-11 22:49

The best way to do this is to create a button, set its background image, and set its action. Then a UIBarButtonItem can be created using this button as the custom view. Here's my example code:

 UIButton *settingsView = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 61, 30)];
[settingsView addTarget:self action:@selector(SettingsClicked) forControlEvents:UIControlEventTouchUpInside];
[settingsView setBackgroundImage:[UIImage imageNamed:@"settings"] forState:UIControlStateNormal];
UIBarButtonItem *settingsButton = [[UIBarButtonItem alloc] initWithCustomView:settingsView];
[self.navigationItem setRightBarButtonItem:settingsButton];
查看更多
孤傲高冷的网名
6楼-- · 2019-01-11 22:50

Set correct image size: @1x = 22px, @2x = 44px @3x = 88px firstly.

Then

let leftBarButtonItem = UIBarButtonItem(image: yourUIImage, style: .plain, target: self, action: #selector(action))
leftBarButtonItem.tintColor = UIColor.red
navigationItem.leftBarButtonItem = leftBarButtonItem

or

let btn = UIButton(type: .custom)
btn.addTarget(self, action: #selector(contactMe), for: .touchUpInside)
btn.setImage(#imageLiteral(resourceName: "open"), for: .normal)
查看更多
Bombasti
7楼-- · 2019-01-11 23:00

For those who have come across this toolbar item stretching issue in iOS 11 specifically, it appears that the @2x version of your image is now required to render its frame and or bounds.

So if you have code like this where you're adding a custom image UIBarButtonItem like this:

UIButton *tagsBtn = [UIButton buttonWithType:UIButtonTypeCustom];
tagsBtn.bounds = CGRectMake( 0, 0, 40, 40);
[tagsBtn setImage:[UIImage imageNamed:@"tags.png"] forState:UIControlStateNormal];
tags = [[UIBarButtonItem alloc] initWithCustomView:tagsBtn];
[tagsBtn addTarget:self action:@selector(tags:) forControlEvents:UIControlEventTouchUpInside];

[bottomToolbar setItems:[NSArray arrayWithObjects:flexibleSpace,tags,flexibleSpace,nil]];

Then you will need to have a tags@2x.png that's 80x80, even if your tags.png image is 80x80. Simply renaming tags.png to tags@2x.png would resize the image to 40x40 as it did pre iOS 11 without changing code, or just add tags@2x.png to your project.

查看更多
登录 后发表回答