UIButton是否不收听内容模式设置?


91

firstButton是自定义类型的UIButton。我以编程方式将它们中的三个放在表的每个单元格上,因此:

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

在其他地方,我告诉它是clipToBounds。我得到的是图像中心正方形的裁剪,而不是图像的纵横比渲染。我尝试了很多方法,包括在firstButton.imageView上设置mode属性,这似乎也不起作用。


1
请参阅下面的克里斯·诺莱特的解决方案:button.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
马特

请参阅stackoverflow.com/a/28205566/481207,其中显示了UIViewContentModeScaleAspectFit需要同时设置contentVerticalAlignment和contentHorizo​​ntalAlignment。
马特

Answers:


186

我有同样的问题。我看到这个问题有点老了,但我想提供一个清晰正确的答案,以在其他人(如我)在搜索结果中弹出时保存一些时间。

我花了一些时间进行搜索和试验,但找到了解决方案。只需在UIButton内设置“隐藏” ImageView的ContentMode。

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

也许这就是丹·雷(Dan Ray)在接受的答案中所暗示的内容,但我怀疑并非如此。


1
不,不是。我确定的解决方案是使用UIImageView来保存图像,然后在其顶部使用类型为“ custom”的透明,透明的UIButton。
丹·雷

Dave,至少在iOS 3.2上,您的解决方案似乎对我不起作用。太糟糕了,因为我希望点击“免费”以突出显示图像。我什至确保在设置contentMode的位置上button.imageView不会为零,然后像设置操作一样在设置contentMode之后设置图像。
雅克

2
为了澄清,“不起作用”表示“图像以其完整分辨率显示,没有按我希望的那样按比例缩小”。
雅克

Jacques,以上内容适用于iOS4.x。不幸的是,在使用v3.2目标进行构建时,我可以重现“不会调整大小”的问题。我尝试更改UIButton视图的框架大小,但这似乎也无济于事。啊。
戴夫

4
请参阅下面的克里斯·诺莱特的解决方案:button.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
马特

74

如果要处理UIButton的图像(而不是backgroundImage),则在UIButton本身或其imageView上设置contentMode无效(尽管有其他答案)。

或者,也可以这样做:

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

或相应地调整图像大小。

或仅使用附加了UITapGestureRecognizer的UIImageView(正确遵守contentMode),或在其顶部使用透明的UIButton。


4
这适用于我在iOS 7中的情况,而此处其他所有情况均不行。
2014年

5
设置contentHorizo​​ntalAlignment和contentVerticalAlignment是正确的解决方案。有关说明,请参见stackoverflow.com/a/28205566/481207
马特

1
这是我一直在寻找的答案。
ninjaneer

4
这个答案是不正确的。你需要设置contentModeimageView,如果你想要做的任何方面的填充或合适的,因为其他的答案已经澄清。请参阅:stackoverflow.com/a/7944316/746890
克里斯·诺莱特

49

与其设置contentMode按钮本身,不如设置contentHorizontalAlignment和设置contentVerticalAlignment属性,并(关键)contentMode设置按钮的,imageView以填充或适配任何类型的外观。这是一个例子:

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

当然,您还可以执行其他操作,例如将按钮的图像对准按钮的顶部。如果您不需要长宽比填充或适合,则可以自己设置对齐方式:

button.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;

在Swift中,您需要使用:

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

此功能适用于所有版本的iOS,包括具有自动版式的最新版本(例如,iOS 4至iOS 11+)。


2
谢谢克里斯-这解决了我的问题,或者更确切地说,它与contentEdgeInsets结合使用,以便将我的图像从顶部边缘稍微退下来。
罗布·罗伊斯

7

经过几个小时的困惑,这就是我如何使其在iOS 3.2下工作。正如黄昏者所提到的,使用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];

6

答案是将UIImageView与所需的所有可爱的“内容模式”设置一起使用,然后在其顶部分层自定义按钮。愚蠢的是您无法一口气完成所有操作,但看来您做不到。


4

找到了解决办法。将的adjustsImageWhenHighlighted属性设置UIButtonNO

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

希望这可以帮助。请随时在下面评论,如果您有任何问题,我都会跟进。


这是完美的解决方案。
Gaurav

不起作用 这仅防止按钮突出显示。
马特

4

我的答案与库巴的答案相似。我需要以编程方式设置图像。

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;
}

3

唯一对我有用的解决方案:

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


1

代替setImage尝试setBackgroundImage


3
嗯 A,这很愚蠢,应该尊重其内容的“内容模式”设置,对吗?B,它似乎仍然不遵守模式设置-它现在被锁定为“拉伸”(在这种情况下,更像是“挤压”),并且没有按照其方面缩放内容比。
丹·雷

1

我相信我们这里有一个简单的界面生成器问题-显然,在您设置了图像属性之后,IB会忽略任何内容模式更改。

解决方案很简单:设置内容模式,删除以前设置的图像名称(确保在所有状态,默认,突出显示等情况下都将其删除),然后在所有所需的状态下重新输入所需的图像名称-等等。


1
以编程方式设置内容模式也是如此-在设置内容模式之前不要设置图像
JohnPayne 2013年

0

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


0

为了弄清楚这一点,随着时间的流逝,我的方法变得有点骇人听闻,然后我总结了UIButton的子类并覆盖了setHighlighted:

对我来说,它只是将图像的alpha压缩为.5,因为它们在黑色背景上。

但是,只有在我注释掉[super setHighlighted:](它似乎正在运行图像可伸缩代码)的情况下,它才起作用,但这根本感觉不到解决此问题的正确方法……一切似乎都是工作正常,但是。当我继续努力时,我们将看到它如何承受。

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

//    [super setHighlighted:highlight];
}

1
偶然的情况下,任何人都认为这相关,我的上述方法似乎可以正常工作,直到我将按钮放在UIScrollView上,有时按钮的高亮部分“卡住了”,这是我怀疑最终可能发生的情况。
詹金斯2012年

0

如果有人在iOS 6,iOS 7和情节提要中寻找可以解决问题的答案:

您可以在情节提要中设置图像:

在此处输入图片说明

然后:

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

0

如果UIButton似乎听不到布局约束设置,请检查图像是否大于按钮大小。始终将@ 2x和@ 3x图像用于视网膜分辨率。


0

这两件事(一开始很难找到)会拉伸UIButton图像以适合按钮大小:

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

人们应该总是尝试在情节提要中设置此类代码,而不是代码。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.