ios 使用 resizableImageWithCapInsets:按钮图像仅适用于状态集,其他状态显示“间隙”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8671315/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using resizableImageWithCapInsets: image for button only works for the state set, other states show a "gap"
提问by NSProgrammer
When using resizableImageWithCapInsets: to create an image for a UIButton only the normal state (the state set the image with using setBackgroundImage:forState:) works. All other states show a gap instead of the drawn image. UIButton says that if no image is set for a particular state, the normal state image will be used with an overlay for disabled and selected states.
当使用 resizableImageWithCapInsets: 为 UIButton 创建图像时,只有正常状态(使用 setBackgroundImage:forState: 设置图像的状态)有效。所有其他状态显示间隙而不是绘制的图像。UIButton 表示如果没有为特定状态设置图像,则正常状态图像将与禁用和选定状态的叠加一起使用。
Here is the normal state:
这是正常状态:
Here is the selected state:
这是选择的状态:
And here is the source image:
这是源图像:
It clearly is using the resizable image I provided, but the image is not drawing the resized area. (You can see the left and right edges but the middle area that is to be stretched just isn't drawn).
它显然使用了我提供的可调整大小的图像,但该图像没有绘制调整大小的区域。(您可以看到左右边缘,但未绘制要拉伸的中间区域)。
Interestingly, stretchableImageWithLeftCapWidth:topCapHeight: does work. Now this is a deprecated method in iOS 5, but with the gap being shown in the new API, I may be stuck using it.
有趣的是,stretchableImageWithLeftCapWidth:topCapHeight: 确实有效。现在这是 iOS 5 中不推荐使用的方法,但由于新 API 中显示了差距,我可能无法使用它。
I do recognize that I can provide more images for each state but that defeats the purpose I'm trying to achieve of reducing memory footprint plus adds extra dependency on my graphics designer which I'd like to avoid.
我确实认识到我可以为每个状态提供更多图像,但这违背了我试图实现的减少内存占用的目的,并且增加了对我想避免的图形设计器的额外依赖。
// This is the gist of the code being used
UIImage* image = [UIImage imageNamed:@"button.png"];
UIEdgeInsets insets = UIEdgeInsetsMake(image.size.height/2, image.size.width/2, image.size.height/2, image.size.width/2);
image = [image resizableImageWithCapInsets:insets];
[self.button setBackgroundImage:image forState:UIControlStateNormal];
// Even doing the following results in the same behaviour
[self.button setBackgroundImage:image forState:UIControlStateSelected];
回答by jrturton
You aren't creating your insets properly for the image capping. I've reproduced your issue and corrected it by using the correct insets.
您没有为图像封顶正确创建插图。我已经重现了您的问题并通过使用正确的插图更正了它。
With your current code, you are creating caps of half of the image height and width - this leaves you with a "stretchable" area of 0x0 pixels - so you get nothing in the middle.
使用您当前的代码,您正在创建图像高度和宽度一半的大写字母 - 这为您留下了一个 0x0 像素的“可拉伸”区域 - 所以您在中间什么都没有。
Why this isn't showing up as wrong in the normal state of the button I'm not sure - perhaps there is some optimisation built in to UIButton to fix things or auto-strectch if you don't supply a stretchable image, and this is not applied to the other states.
为什么这在按钮的正常状态下没有显示为错误我不确定 - 如果您不提供可拉伸的图像,UIButton 可能内置了一些优化来修复问题或自动拉伸,而这个不适用于其他州。
The caps are supposed to define the area of the image that must not be stretched. In the case of your button.png image, this is 6 pixels on the left and right sides, and 16 pixels in from the top and bottom. This isn't quite standard, you should tell your graphics designer that (at least for left-right which is the most common stretching) you should only have a 1px area in the centre, however this does not affect the outcome. If you do have a 1px stretchable area then you can standardise your code by deriving the caps from the image size as you have tried to do in your question (each cap is then (image.size.height - 1) / 2
for top/bottom, same but with width for left/right).
大写应该定义不得拉伸的图像区域。对于 button.png 图像,左侧和右侧各 6 个像素,顶部和底部各 16 个像素。这不是很标准,您应该告诉您的图形设计师(至少对于最常见的左右拉伸)您应该在中心只有 1px 区域,但这不会影响结果。如果您确实有一个 1px 的可拉伸区域,那么您可以按照您在问题中尝试做的那样,通过从图像大小中导出大写来标准化您的代码(每个大写然后(image.size.height - 1) / 2
用于顶部/底部,相同但宽度为左/右) .
To get the correct images on your button, use the following code for creating the stretchable image:
要在按钮上获得正确的图像,请使用以下代码创建可拉伸图像:
UIEdgeInsets insets = UIEdgeInsetsMake(16, 6, 16, 6);
image = [image resizableImageWithCapInsets:insets];
回答by MikecheckDev
I was experiencing problems while using resizable images on iOS5 too. It turns out that if your button is of type "RountedRect" and you manipulate the background images, the resizable images will not behave as expected. (iOS6 handles this ok, presumably by assuming your new button type and adjusting as needed.)
我在 iOS5 上使用可调整大小的图像时也遇到了问题。事实证明,如果您的按钮是“RountedRect”类型并且您操作背景图像,则可调整大小的图像将不会按预期工作。(iOS6 可以处理这个问题,大概是通过假设您的新按钮类型并根据需要进行调整。)