UIButton无法在iPhone中使用Aspect Fit


105

我有几个UIButton,在IB中将它们设置为Aspect Fit,但是由于某些原因,它们总是在拉伸。您还需要设置其他内容吗?我尝试了所有不同的视图模式,但它们都不起作用,它们都可以拉伸。


@Werner Altesischer的答案是正确的。进行适当的更改。
Harshit Gupta 2014年

1
@marty您要设置背景图像还是图像?背景图片不支持,仅支持图片。
Juan Boero

Answers:


45

我以前有过这个问题。我通过把我的形象在解决了这个问题UIImageView,在这里contentMode设置的实际工作,并把一个透明的定制UIButton过的那顶。

编辑:这个答案已经过时了。有关现代版本iOS的正确答案,请参见@Werner Altewischer的答案


是的,我们尝试过这种方法,但是现在无法获得用于调整图像的按钮
marty 2010年

您如何使用这种技术管理按钮状态?像响应“突出显示”这样的用户交互似乎是一场噩梦。
SooDesuNe

3
这可能是2.5年前回答此问题时的正确方法,但是现在您可以编辑UIButton的内部ImageView并在此处设置内容模式。请参阅@Werner Altewischer的答案
Steve Haley,

233

解决方案是contentMode在的imageView属性上设置UIButton。在UIButton必须与自定义类型(否则就创建了这个工作,我相信nil返回该属性)。


67
这对我[button.imageView setContentMode:UIViewContentModeScaleAspectFit];
有用

2
这对我也适用,但是如果我设置adjustsImageWhenHighlighted = YES,则当我点击按钮时,图像将再次被拉伸。
cduck 2012年

1
iOS 6中已消除了adjustsImage中的拉伸。–
Ben Flynn

3
在iOS 8中,这实际上对我不起作用。原始答案(将imageView放在透明按钮后面)效果最佳。
user1416564

3
在Swift du jour:button.imageView!.contentMode = UIViewContentMode.scaleAspectFit
Nestor

57

这种方法对我非常有效。

Xib中,选择按钮并设置user defined runtime attributes

  • 关键路径: self.imageView.contentMode
  • 类型: Number
  • 值: 1

单击此处以更清楚地了解解决方案

我们使用数字,因为您不能在那里使用枚举。但是UIViewContentModeScaleAspectFit等于1。


2
这还会在设计时更新界面生成器中的图像。很好的解决方案。
乔治·菲利帕科斯

很棒的解决方案,很少的代码,就像个魅力,枚举基于内容模式列表项。
克罗斯(Kross)

您还可以添加扩展名使其更容易一些: extension UIButton { @IBInspectable var imageContentMode: Int { get {return imageView?.contentMode.rawValue ?? 0} set {imageView?.contentMode = UIViewContentMode(rawValue: newValue) ?? .scaleAspectFit} } }
Yonat

没有“自我” imageView.contentMode为我工作!
byJeevan '17

22

如果在Interface Builder中执行此操作,则可以使用“运行时属性”检查器直接设置它,而无需任何代码。

将按钮上的“键路径”设置为“ imageView.contentMode”,类型为“数字”,值为“ 1”(或您想要的任何一种模式)。

imageview.contentMode = 1


14

将按钮的imageView用于contentMode。不直接在按钮本身上。

homeButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
homeButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
homeButton.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
[homeButton setImage:[UIImage imageNamed:kPNGLogo] forState:UIControlStateNormal];

6

如果将图像放在UIImageView按钮后面,则会失去UIButton该类的内置功能,例如adjustsImageWhenHighlightedadjustsImageWhenDisabled,当然也可以为不同的状态设置不同的图像(无需自己动手做)。

如果要使所有控制状态的图像均未拉伸,则一种方法是使用来获取图像imageWithCGImage:scale:orientation,如以下方法所示:

- (UIImage *) getScaledImage:(UIImage *)img insideButton:(UIButton *)btn {

    // Check which dimension (width or height) to pay respect to and
    // calculate the scale factor
    CGFloat imgRatio = img.size.width / img.size.height, 
            btnRatio = btn.frame.size.width / btn.frame.size.height,
            scaleFactor = (imgRatio > btnRatio 
                           ? img.size.width / btn.frame.size.width
                           : img.size.height / btn.frame.size.height;

    // Create image using scale factor
    UIImage *scaledImg = [UIImage imageWithCGImage:[img CGImage]
                                             scale:scaleFactor
                                       orientation:UIImageOrientationUp];
    return scaledImg;
}

为了实现这一点,我们将编写:

UIImage *scaledImg = [self getScaledImage:myBtnImg insideButton:myBtn];
[myBtn setImage:scaledImg forState:UIControlStateNormal];

这样可以防止图像在所有控制状态下拉伸。它对我有用,但如果不行,请告诉我!

注意:在这里,我们正在解决与有关的问题UIButton,但insideButton:也可能是insideView:,或任何想要使图像适合的问题。


6

我前一段时间有这个问题。我遇到的问题是我试图将这种效果应用于背景UIButton,这是有限的,因此意味着您无法轻松地对其进行调整。

诀窍是将其设置为仅图像,然后应用@ayreguitar的技术,这应该可以解决它!

UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];
[myButton setContentMode:UIViewContentModeScaleAspectFill];
[myButton setImage:@"myImage.png" forState:UIControlStateNormal];



4

将几个不同的答案组合到一个解决方案中-创建具有自定义类型的按钮,设置按钮的imageView contentMode属性,并设置按钮的图像(而不是背景图像,该图像仍会缩放以填充)。

//Objective-C:
UIImage *image = [UIImage imageNamed:"myImageName.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:image forState:UIControlStateNormal];
button.imageView.contentMode = UIViewContentModeScaleAspectFit;

//Swift:
let image = UIImage(named: "myImageName.png")
let button = UIButton(type: .custom)
button.imageView?.contentMode = .scaleAspectFit
button.setImage(image, for: .normal)

3
btn.imageView.contentMode = UIViewContentModeScaleAspectFit;

尽管此代码段可以解决问题,但提供说明确实有助于提高您的帖子质量。请记住,您将来会为读者回答这个问题,而这些人可能不知道您提出代码建议的原因。- 从回顾
Ferrybig

2

该答案基于@WernerAltewischer的答案

为了避免将我的按钮连接到IBOutlet来执行代码,我将UIButton的类子类化:

// .h
@interface UIButtonWithImageAspectFit : UIButton
@end

// .m
@implementation UIButtonWithImageAspectFit

- (void) awakeFromNib {
    [self.imageView setContentMode:UIViewContentModeScaleAspectFit];
}

@end



现在,在xib中创建一个自定义按钮,并设置其图像(而不是背景图像):

UIButtonWithImageAspectFit:创建和设置图像


然后,设置其类:

UIButtonWithImageAspectFit:设置自定义类

你完成了!
而不是
没有图像外观适合的UIButton
你的按钮的图像纵横适合现在的预期:
具有图像外观的UIButton


2

ios12。您还需要添加内容“对齐”

class FitButton: UIButton {

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)


    }

    override func layoutSubviews() {
        self.imageView?.contentMode = .scaleAspectFill
        self.contentHorizontalAlignment = .fill
        self.contentVerticalAlignment = .fill
        super.layoutSubviews()


    }

}

1

我遇到了图像无法按比例调整大小的问题,因此我修复它的方法是使用边缘插图。

fooButton.contentEdgeInsets = UIEdgeInsetsMake(10, 15, 10, 15);

1

UIView内容模式适用于相应的CALayer的“内容”。这适用于,UIImageView因为他们将CALayer内容设置为CGImage

drawRect: 最终呈现给图层内容。

一个自定义项UIButton(据我所知)没有内容(四舍五入的样式按钮可能使用内容来呈现)。该按钮具有子视图:背景UIImageView,图像UIImageView和标题UILabelcontentMode在子视图上设置可能会做您想要的事情,但是弄乱UIButton视图层次结构有点不可或缺。


1

改变UIButton.imageView.contentMode对我没有用。
我通过将图像设置为“背景”属性解决了该问题。
您可以根据需要添加比率约束


1

这与许多其他答案重叠,但是对我来说解决方案是

  • 设置contentModeUIImageView用于按钮.ScaleAspectFit-这可以在完成“定义运行时用户属性”在界面生成器(即self.imageView.contentMode,数字,1),或在一个UIButton子类;
  • 禁用“自动调整子视图大小”;
  • 将“边缘”设置为“图像”,并为“插入”设置适当的“顶部”和“底部”值(仅当您像我一样使用PDF作为图像时才需要)。

0

您可以使用如上所示的imageWithCGImage(但不要缺少括号)。

另外...数百万非4.0手机根本无法使用该代码。



0

类似于@Guillaume,我创建了UIButton的子类作为Swift-File。然后在Interface Builder中设置我的自定义类:

界面构建器

这是Swift文件:

import UIKit

class TRAspectButton : UIButton {
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.imageView?.contentMode = .ScaleAspectFit
    }
}

-1

我遇到了同样的问题,但无法正常工作(也许这是SDK的错误)。

最终,作为一种解决方法,我UIImageView在按钮后面放置了一个按钮,并设置了所需的选项,然后UIButton在其顶部放置了一个空白。


7
这里有回声吗?;-)
Dan Ray 2010年
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.