简体   繁体   English

UIButton 不听内容模式设置?

[英]UIButton doesn't listen to content mode setting?

firstButton is a UIButton of type Custom. firstButton 是一个自定义类型的 UIButton。 I'm programmatically putting three of them across each cell of a table, thusly:我以编程方式将其中三个放在表格的每个单元格中,因此:

[firstButton setImage:markImage forState:UIControlStateNormal];
[firstButton setContentMode:UIViewContentModeScaleAspectFit];
[cell.contentView addSubview:firstButton];

Elsewhere, I'm telling it to clipToBounds.在其他地方,我告诉它clipToBounds。 What I get is a crop of the center square of the image, rather than an aspect-scaled rendering of it.我得到的是图像中心正方形的裁剪,而不是它的纵横比例渲染。 I've tried this lots of ways, including setting the mode property on firstButton.imageView, which also doesn't seem to work.我已经尝试了很多方法,包括在 firstButton.imageView 上设置 mode 属性,这似乎也不起作用。

I had the same problem.我有同样的问题。 I see this question is a little old, but I want to provide a clear and correct answer to save other folks (like me) some time when it pops up in their search results.我看到这个问题有点老了,但我想提供一个清晰正确的答案,以节省其他人(如我)在搜索结果中弹出的时间。

It took me a bit of searching and experimenting, but I found the solution.我花了一些搜索和试验,但我找到了解决方案。 Simply set the ContentMode of the "hidden" ImageView that is inside the UIButton.只需设置 UIButton 内的“隐藏”ImageView 的 ContentMode。

[[firstButton imageView] setContentMode: UIViewContentModeScaleAspectFit];
[firstButton setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];

Perhaps that's what Dan Ray was alluding to in his accepted answer, but I suspect not.也许这就是丹雷在他接受的答案中暗指的,但我怀疑不是。

If you're dealing with the UIButton's image (as opposed to it's backgroundImage), setting the contentMode on the UIButton itself or on its imageView has no effect (despite what other answers say).如果您正在处理 UIButton 的图像(而不是它的 backgroundImage),则在 UIButton 本身或其 imageView 上设置 contentMode 没有效果(尽管其他答案是这样说的)。

Alternatively do this instead:或者这样做:

self.button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
self.button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;

Or size your image accordingly.或相应地调整图像大小。

OR just use a UIImageView (which properly respects contentMode) with a UITapGestureRecognizer attached to it, or a transparent UIButton on top of it.或者只使用一个 UIImageView(它正确地尊重 contentMode)和一个 UITapGestureRecognizer 附加到它,或者一个透明的 UIButton 在它上面。

Rather than setting the contentMode on the button itself, you'll want to set contentHorizontalAlignment and contentVerticalAlignment properties and (crucially) the contentMode for the button's imageView for any kind of aspect fill or fit.而不是设置contentMode按钮本身,你要设置contentHorizontalAlignmentcontentVerticalAlignment性能和(关键)的contentMode为按钮的imageView任何种类方面的填充或适合的。 Here's an example:下面是一个例子:

button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
button.imageView.contentMode = UIViewContentModeScaleAspectFit;

Of course, you can also do other things like aligning the button's image to the top of the button.当然,您还可以执行其他操作,例如将按钮的图像与按钮顶部对齐。 If you don't need an aspect fill or fit, you just can set the alignment by itself:如果您不需要方面填充或适合,您可以自行设置对齐方式:

button.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;

In Swift, you'll want to use:在 Swift 中,您需要使用:

button.contentHorizontalAlignment = .fill
button.contentVerticalAlignment = .fill
button.imageView?.contentMode = .scaleAspectFit

This works for all versions of iOS, including the latest versions with auto-layout, (ie iOS 4 up to iOS 11+).这适用于所有版本的 iOS,包括具有自动布局的最新版本(即 iOS 4 到 iOS 11+)。

After a couple of hours of confusion, here's how I got it to work under iOS 3.2.经过几个小时的困惑,以下是我如何让它在 iOS 3.2 下工作。 As dusker mentioned, using setBackgroundImage instead of setImage did the job for me.正如 dusker 所提到的,使用 setBackgroundImage 而不是 setImage 为我完成了这项工作。

CGRect myButtonFrame = CGRectMake(0, 0, 250, 250);
UIImage *myButtonImage = [UIImage imageNamed:@"buttonImage"];

UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];

[myButton setBackgroundImage:myButtonImage forState:UIControlStateNormal];
[myButton setFrame: myButtonFrame];
[myButton setContentMode: UIViewContentModeScaleAspectFit];

The answer is to use a UIImageView with all the lovely Content Mode settings you want, and then layer a custom button on top of it.答案是使用 UIImageView 和你想要的所有可爱的内容模式设置,然后在它上面放置一个自定义按钮。 Dumb that you can't do that all in one shot, but it appears that you can't.愚蠢的是你不能一次完成所有的事情,但看起来你不能。

Found a fix for this.找到了解决方法。 Set the adjustsImageWhenHighlighted property of UIButton to NO .UIButtonadjustsImageWhenHighlighted属性设置为NO

  UIButton *b = [[UIButton alloc] initWithFrame:rect];
        [b setImage:image forState:UIControlStateNormal];
        [b.imageView setContentMode:UIViewContentModeScaleAspectFill];
        [b setAdjustsImageWhenHighlighted:NO];

Hope this helps.希望这可以帮助。 Feel free to comment below, I will follow up on any questions that you have.欢迎在下方留言,有任何问题我都会跟进。

My answer is similar to Kuba's.我的答案与库巴的相似。 I needed my image to be programatically set.我需要以编程方式设置我的图像。

UIImage *image = [[UIImage alloc] initWithContentsOfFile:...];
[button setBackgroundImage:image forState:UIControlStateNormal];
button.imageView.contentMode = UIViewContentModeScaleAspectFill; //this is needed for some reason, won't work without it.
for(UIView *view in button.subviews) {
    view.contentMode = UIViewContentModeScaleAspectFill;
}

These two things (which are quite hard to find initially) will stretch your UIButton image to fit the button size:这两件事(最初很难找到)会拉伸你的 UIButton 图像以适应按钮大小:

在此处输入图片说明 在此处输入图片说明

one should always try to set such in the Storyboard rather than code.人们应该始终尝试在 Storyboard 而不是代码中设置这样的设置。

Only solution which worked for me:唯一对我有用的解决方案:

[button setImage:image forState:UIControlStateNormal];
button.imageView.contentMode = UIViewContentModeScaleAspectFill;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;

斯威夫特 3

self.firstButton.imageView?.contentMode = .scaleAspectFill

I believe we have a simple interface builder issue here - apparently the IB ignores any content-mode changes AFTER you have set the image-property.我相信我们在这里有一个简单的界面构建器问题 - 显然,在您设置图像属性后,IB 会忽略任何内容模式更改。

the solution is as simple: set the content mode, remove previously set image-names (make sure you remove it in all states, default, highlighted etc.), then re-enter the desired image-names in all desired states - et voilà.解决方案很简单:设置内容模式,删除之前设置的图像名称(确保在所有状态、默认、突出显示等中将其删除),然后在所有所需状态中重新输入所需的图像名称 - 等等.

而不是 setImage 尝试 setBackgroundImage

If anyone looking for answer that work in iOS 6 and iOS 7 and storyboard:如果有人正在寻找适用于 iOS 6 和 iOS 7 以及故事板的答案:

You can set image in your storyboard:您可以在故事板中设置图像:

在此处输入图片说明

And then:进而:

for(UIView* testId in self.subviews) {
    if([testId isKindOfClass:[UIImageView class]])
        [testId setContentMode:UIViewContentModeScaleAspectFill];
}

我还建议查看adjustsImageWhenHighlighted UIButton属性,以避免在按下按钮时图像出现奇怪的变形。

If the UIButton does not seem to listen to the layout constraint settings, do check whether the images are larger than the button size.如果 UIButton 似乎没有监听布局约束设置,请检查图像是否大于按钮大小。 Always use the @2x and @3x images for retina resolutions.对于视网膜分辨率,始终使用 @2x 和 @3x 图像。

For anyone experiencing this on iOS 15 and Xcode 13, see Matt's answer in this other question .对于在 iOS 15 和 Xcode 13 上遇到此问题的任何人,请参阅Matt 在其他问题中的回答

The behavior of Xcode changed and now defaults UIButtons from the library to the plain style, which prevents the child image from scaling as expected. Xcode 的行为发生了变化,现在将库中的 UIButtons 默认为plain样式,这会阻止子图像按预期缩放。

In trying to figure this out, my method got a bit hackier as time went on, and I wound up subclassing UIButton and overriding setHighlighted:为了解决这个问题,随着时间的推移,我的方法变得有点棘手,我最终继承了 UIButton 并覆盖了 setHighlighted:

For me it works to just knock down the image alpha to .5, because they're on a black background.对我来说,只需将图像 alpha 降低到 0.5 即可,因为它们位于黑色背景上。

However, it only works if I comment out [super setHighlighted:] (where it appears the image-stretchy code is going on), which just doesn't feel like the right way to solve this at all...everything seems to be working fine, though.然而,它只有在我注释掉 [super setHighlighted:](它出现图像拉伸代码正在进行的地方)时才有效,这根本不是解决这个问题的正确方法......一切似乎都是不过,工作正常。 We'll see how it holds up as I keep working on it.当我继续努力时,我们将看到它的表现如何。

- (void)setHighlighted:(BOOL)highlight {
    if (highlight) {
        [self.imageView setAlpha:.5];
    }  else {
        [self.imageView setAlpha:1];        
    }

//    [super setHighlighted:highlight];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM