将UIImage放入UIButton的简单方法

时间:2010-12-21 17:16:29

标签: iphone image uiimageview uibutton aspect-ratio

我的iPhone应用程序中有一个UIButton。我将其大小设置为100x100。

我有一个400x200的图像,我希望在按钮中显示。

按钮STILL需要保持在100x100 ......我希望图像缩小以适应......但是 保持正确的宽高比。

我认为这就是“Aspect Fit”的用途。

我是否使用setImage或setBackgroundImage包含我的图像?

我是否为按钮设置了AspectFit?还是形象?还是背景图片?

(我需要较小的图像来增加大小。虽然较大的图像应该是DESCREASE的大小。 始终将按钮保持在100x100。)

我尝试了以上所有的无数组合......而我似乎无法得到 一切都在同一时间工作:

  • 请勿将按钮的大小更改为100x100。
  • 不要破坏图像的宽高比。
  • 始终增加小图像以适应按钮。
  • 始终减小大图像以适应按钮。
  • 永不剪裁任何图像边缘。
  • 永远不要求“将UIButtons放在所有UIimages上”hack。
  • 不要求每个人都只是为了使用新的框架方法而升级到v4.2.1。

我看到很多应用程序,有如此多的全功能图像按钮......我无法相信我无法弄清楚这个非常简单,非常常见的事情。

呃。

8 个答案:

答案 0 :(得分:12)

UIButton坏了。这是简短的答案。其image和backgroundImage属性中的UIImageView不尊重UIViewContentMode设置。它们是只读属性,虽然可以通过UIImagesetImage:方法设置这些UIImageViews的setBackgroundImage:内容,但内容模式不能。

解决方案是要么首先在捆绑包中提供尺寸合适的图像,要么放下UIImageView,按照您想要的方式配置它,然后在其上面放置一个清晰的“自定义”UIButton。我保证,这就是你见过的那些花哨的专业应用程序。我们都必须这样做。

答案 1 :(得分:6)

UIImage *img = [UIImage imageNamed:@"yourImageName"];
button.imageView.contentMode = UIViewContentModeScaleAspectFit;
[button setImage:img forState:UIControlStateNormal];

答案 2 :(得分:4)

为了正确地执行此操作,我实际上将以编程方式调整大小并操纵图像以获得所需的宽高比。这样就不需要任何视图层次结构黑客攻击,也可以减少对单个操作的性能影响,而不是每次重绘。

这个(未经测试的)代码应该有助于说明我的意思:

CGSize imageSize = image.size;
CGFloat currentAspect = imageSize.width / imageSize.height;

// for purposes of illustration
CGFloat targetWidth = 100;
CGFloat targetHeight = 100;
CGFloat targetAspect = targetWidth / targetHeight;

CGFloat newWidth, newHeight;

if (currentAspect > targetAspect) {
    // width will end up at 100, height needs to be smaller
    newWidth = targetWidth;
    newHeight = targetWidth / currentAspect;
} else {
    // height will end up at 100, width needs to be smaller
    newHeight = targetHeight;
    newWidth = targetHeight * currentAspect;
}

size_t bytesPerPixel = 4;

// although the image will be resized to { newWidth, newHeight }, it needs
// to be padded with empty space to provide the aspect fit behavior
//
// use calloc() to clear the data as it's allocated
void *imageData = calloc(targetWidth * targetHeight, bytesPerPixel);

if (!imageData) {
    // error out
    return;
}

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
if (!colorSpace) {
    // error out
    return;
}

CGContextRef context = CGBitmapContextCreate(
    imageData,
    targetWidth,
    targetHeight,
    8, // bits per component
    targetWidth * bytesPerPixel, // bytes per row
    colorSpace,
    kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst
);

CGColorSpaceRelease(colorSpace);

// now we have a context to draw the original image into
// in doing so, we want to center it, so prepare the geometry
CGRect drawRect = CGRectMake(
    floor((targetWidth - newWidth) / 2),
    floor((targetHeight - newHeight) / 2),
    round(newWidth),
    round(newHeight)
);

CGContextDrawImage(context, drawRect, image.CGImage);

// now that the bitmap context contains the aspect fit image with transparency
// letterboxing, we want to pull out a new image from it
CGImageRef newImage = CGBitmapContextCreateImage(context);

// destroy the temporary context
CGContextRelease(context);
free(imageData);

// and, finally, create a new UIImage
UIImage *newUIImage = [UIImage imageWithCGImage:newImage];
CGImageRelease(newImage);

如果有任何部分不清楚,请告诉我。

答案 3 :(得分:2)

我认为Dan试图说的是(但没有说过)是这样做的:

  • 使用“临时图像”为您调整大小。
  • 需要将临时图像设置为ASPECT FIT和HIDDEN。
  • 确保您的按钮设置为所需的尺寸,而不是设置为ASPECT FIT。
// Make a frame the same size as your button
CGRect aFrame = CGRectMake(0, 0, myButton.frame.size.width, myButton.frame.size.height);

// Set your temp-image to the size of your button
imgTemp.frame = aFrame;

// Put your image into the temp-image
imgTemp.image = anImage;

// Copy that resized temp-image to your button
[myButton setBackgroundImage:tempImage forState:UIControlStateNormal]; 

答案 4 :(得分:2)

因为我的尝试都没有奏效....

也许我应该问这个问题。使用UIButton时:

DO 时,我使用setImage而不是setBackgroundImage? (为什么两者都有?)

DO 时,我使用“Aspect Fit”而不是“Center”? (为什么当我期望它们“保持纵横比”和“不调整任何东西”时,两者似乎都会拉伸我的图像。)

还有一个大问题:为什么这么常见?这么大的混乱?

如果我能找到一种类似的解决方法,它将全部解决:只需使用UIImage并检测TAPS。 (但这似乎甚至是代码的最大噩梦。)

Apple,如果你试图让我的工作变得更轻松......你却让它变得混乱了400倍。

答案 5 :(得分:1)

在按钮上放置一个图像视图,为图像视图设置图像而不是按钮。

一切顺利。

答案 6 :(得分:1)

我会将图像调整为100x100,保持图像中包含的内容的宽高比。然后将UIButton的backgroundImage属性设置为图像。

答案 7 :(得分:0)

我几天前遇到同样的问题并解决了。请尝试使用此

[_profilePicBtn setImage:profilePic forState:UIControlStateNormal];
_profilePicBtn.imageView.contentMode = UIViewContentModeScaleAspectFit;