12

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

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

按钮仍然需要保持在 100x100 ......我希望图像缩小以适应......但保持正确的纵横比。

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

我是否将我的图像包含在 setImage 或 setBackgroundImage 中?

我是否为按钮设置 AspectFit?还是图像?还是背景图片?

(我需要较小的图像来增加尺寸。而较大的图像应该减小尺寸。始终将按钮保持在 100x100。)

我已经尝试了上述所有方法的无数组合......我似乎无法让所有东西同时工作:

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

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

啊。

4

8 回答 8

12

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

解决方案是在你的包中提供适当大小的图像,或者放下 UIImageView,按照你想要的方式配置它,然后在它上面放置一个清晰的“自定义”UIButton。我保证,这就是你见过的所有花哨的专业应用程序所使用的技巧。我们都必须这样做。

于 2010-12-21T21:07:45.007 回答
6
UIImage *img = [UIImage imageNamed:@"yourImageName"];
button.imageView.contentMode = UIViewContentModeScaleAspectFit;
[button setImage:img forState:UIControlStateNormal];
于 2013-08-15T12:42:28.713 回答
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);

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

于 2010-12-21T21:38:56.020 回答
2

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

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

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

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

还有一个大问题:为什么如此普遍的事情……如此巨大的混乱?

如果我能找到一种解决方法,例如:只需使用 UIImage 并检测 TAPS,这一切都将得到解决。(但这似乎是一场更大的代码噩梦。)

苹果,如果你试图让我的工作更轻松……你反而让它变得更加混乱 400 倍。

于 2010-12-21T21:59:16.443 回答
2

我认为 Dan 想说的(但从未说过)是这样做的:

  • 使用“临时图像”为您调整大小。
  • 临时图像需要设置为 ASPECT FIT 和 HIDDEN。
  • 确保您的按钮设置为您想要的大小,而不是设置为 ASPECT FIT。
// 制作与按钮大小相同的框架
CGRect aFrame = CGRectMake(0, 0, myButton.frame.size.width, myButton.frame.size.height);

// 将临时图像设置为按钮的大小
imgTemp.frame = aFrame;

// 将你的图像放入临时图像
imgTemp.image = anImage;

// 将调整大小的临时图像复制到您的按钮
[myButton setBackgroundImage:tempImage forState:UIControlStateNormal];
于 2010-12-21T21:00:51.200 回答
1

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

一切顺利。

于 2010-12-21T17:20:43.897 回答
1

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

于 2010-12-21T18:52:54.213 回答
0

几天前我遇到了同样的问题并解决了它。请试试这个

[_profilePicBtn setImage:profilePic forState:UIControlStateNormal];
_profilePicBtn.imageView.contentMode = UIViewContentModeScaleAspectFit;
于 2014-10-14T08:49:47.187 回答