2011-12-30 196 views
47

我将一个UIButtonTypeCustom UIButton分配给一个背景图像小于按钮的框架的UIView。为什么图像更小的原因是因为我试图为UIButton添加更多的“目标区域”。但是,图像被缩放为整个框架的大小,而不仅仅是图像的大小。如何防止按钮的背景图片拉伸?

我曾尝试将UIButton和UIButton的imageView contentMode属性设置为“UIViewContentModeScaleAspectFit”,但没有运气,图像仍然伸出。

有没有办法做我想以编程方式做什么?

在此先感谢!

+4

你真的需要它的背景图片?你是否需要真正写文本或在其上放置另一个图像?如果没有,则使用图像而不使用背景图像,因为默认情况下仅将背景图像拉伸以匹配框架。 – 2012-01-11 18:43:41

+0

@Raphael这些答案都不合适吗? – memmons 2013-10-01 20:00:28

回答

-2

你需要做的是添加你的图像作为UIImageView。

比你想要的宽度和高度添加与transperent背景(UIColor ClearColor)顶部的按钮。

+0

这实际上是一个不好的建议,因为图像不会成为按钮的一部分,并且不会反映状态的变化(这会影响将图像作为按钮的一部分的目的)。 – GtotheB 2013-03-12 00:15:55

+0

为此,您可以在点击按钮时更改图像以模仿状态更改 – ozba 2013-03-12 08:35:56

+0

@ozba按钮上已经支持图像的状态更改。在清晰按钮后面添加背景图像以模仿带有图像的按钮几乎不是一个好主意,通常也是一个非常糟糕的主意。 – memmons 2013-09-05 14:38:06

120

很多人在按钮图像方面犯了同样的错误,然后跳过箍环试图让按钮按照他们的期望行事。让我们一劳永逸地澄清:

A UIButton有两种类型的图像可以显示 - 前景图像和背景图像。预计按钮的背景图像将取代按钮的背景纹理。因此,延伸以填充整个背景是有意义的。然而,按钮的前景图像预计是一个图标,可能会或可能不会显示旁边的文字;它不会伸展。可能收缩,如果框架比图像小,但它不会伸展。您甚至可以使用Interface Builder中的控件对齐属性设置前景图像的对齐方式。

A按钮的前景和背景图像可以在代码中设置这样的:

// stretchy 
[self setBackgroundImage:backgroundImage forState:UIControlStateNormal]; 

// not stretchy 
[self setImage:forgroundImage forState:UIControlStateNormal]; 
+49

当你需要一个非伸缩图像时,你会怎么做? – 2012-12-23 13:19:24

+0

奇怪的是,每当我设置UIButton图像属性标题文本消失。有没有办法阻止?编辑:哦,文字是在右边..奇怪,我想我只是玩调整,直到它直接在前景图像 – powerj1984 2013-05-28 16:59:39

+0

@ powerj1984如果你想要文字坐在图像的顶部,你应该是使用backgroundImage。预计前景图像将取代文字或与文字并排放置。如果你正在调整你的文本,强迫它坐在前景图像的顶部,那么你做错了。 – memmons 2013-05-31 02:42:16

0

另一个考虑是基线约束。如果您的按钮具有此约束设置(通过布局中的多个控件描绘为水平或垂直线),则会导致您的图像拉伸,而不会拉伸底层的按钮控件。如果您的按钮在其他方面受到了适当的约束(前导/尾随和顶部/底部空间等),则删除BaseLine约束应该不会影响布局,同时允许前景图像正确缩放到底层按钮形状。

-1

Answerbot用正确和正确的答案来回答问题。不要反对操作系统和按预期使用东西总是很好的建议。但是,有时你需要打破规则。

我能够通过用黑色CAlayer覆盖放大的背景图像(而不是阻止它),然后再次与正确调整大小的图像CAlayer重叠。这一切都是通过创建UIButton的子类并覆盖setHighlighted方法来完成的。

需要帮助?

- (void)setHighlighted:(BOOL)highlighted 
{ 
super.highlighted = highlighted; 

// 
//Whenever an image needs to be highlighted, create a dimmed new image that is correctly  sized. Below it is a englarged stretched image. 
// 
if (highlighted != _previousHighlightedSate) 
{ 
    _previousHighlightedSate = highlighted; 

    if (highlighted) 
    { 
     //Create a black layer so image can dim 
     _blackLayer = [CALayer layer]; 
     _blackLayer.bounds = self.bounds; 
     CGRect rect = _blackLayer.bounds; 
     rect.size.width = rect.size.width*2; 
     rect.size.height = rect.size.height*2; 
     _blackLayer.bounds = rect; 
     _blackLayer.backgroundColor = [[UIColor blackColor] CGColor]; 

     //create image layer 
     _nonStretchImageLayer = [CALayer layer]; 
     _nonStretchImageLayer.backgroundColor = [UIColor blackColor].CGColor; 
     _nonStretchImageLayer.bounds = CGRectMake(0 , 0, self.bounds.size.width, self.bounds.size.height); 
     _nonStretchImageLayer.frame = CGRectMake(0 , 0, self.bounds.size.width, self.bounds.size.height); 
     _nonStretchImageLayer.contentsGravity = kCAGravityResizeAspect;//default is to resize 
     _nonStretchImageLayer.contents = (id)self.imageView.image.CGImage; 
     _nonStretchImageLayer.opacity = 0.5; 

     //add layers to image view 
     [self.imageView.layer addSublayer:_blackLayer]; 
     [self.imageView.layer addSublayer:_nonStretchImageLayer]; 
    } 
    else 
    { 
     //remove from image view 
     [_blackLayer removeFromSuperlayer]; 
     [_nonStretchImageLayer removeFromSuperlayer]; 

     //nil them out. 
     _blackLayer = nil; 
     _nonStretchImageLayer = nil; 
    } 
} 

灵感这项工作从here

0

各地来到我想最简单的解决方法是使用的UIImage的resizableImageWithCapInsets方法。使用UIEdgeInsetsMake配置空闲空间。

1

它可能使用按钮的标题插图最清洁和最简单的方法。

你设置你的图像作为按钮图像,然后更改左标题插图,以配合减去图像的宽度:

myButton.titleEdgeInsets = UIEdgeInsetsMake(0, -myImage.width, 0, 0) 

这将文本搬回它是影像在添加到其左侧。您也可以使用此值为您添加一些填充按钮。

6

您没有访问后台的ImageView,但完全正常的解决方法:

编辑:有一个更好的解决办法又是什么我张贴原本。 你可以从任何颜色营造的UIImage,并调用-setBackgroundImage:forState.

bradley's答案,在这里: https://stackoverflow.com/a/20303841/1147286


原来的答复:

调用-setBackgroundImage:forState:的相反,创建一个新的UIImageView并将其添加为按钮的子视图。

UIImageView *bgImageView = [[UIImageView alloc] initWithImage:img]; 
bgImageView.contentMode = UIViewContentModeScaleAspectFit; 
[bgImageView setFrame:CGRectMake(0, 0, videoButton.frame.size.width, videoButton.frame.size.height)]; 
bgImageView.tag = 99; 
[yourButton addSubview:bgImageView]; 
[yourButton bringSubviewToFront:yourButton.imageView]; 
  1. 创建的ImageView
  2. 设置内容模式和框架
  3. 我还设置了识别标签,这样,当屏幕旋转时,我可以很容易地找到按钮的子视图我自定义的ImageView和复位其框架
  4. 作为一个子视图将它添加到该按钮
  5. 带按钮的正面的ImageView到前面所以我们自定义的ImageView的不重叠它

当按钮需要旋转刚找到其标签的ImageView和复位它的框架:

UIImageView *bgImageView = (UIImageView *)[button viewWithTag:99]; 
[bgImageView setFrame:CGRectMake(0, 0, newWidth, newHeight)]; 
0

无意中发现这个问题了。

添加图像编程,如memmons有详尽的解释,并没有帮助:(

我有一个按钮100x40和100x100的图像,它会出现挤压,不装,因为人们从推断出“宽适应”的选项。其实,这些视图选项中没有一个有效。

我不得不重新调整它,所以它会适合上的按钮,然后使用setImage:

UIImage *img=[UIImage imageNamed:@"myimage.png"]; 
CGImageRef imgRef = [img CGImage]; 
CGFloat imgW = CGImageGetWidth(imgRef); 
CGFloat imgH = CGImageGetHeight(imgRef); 
CGFloat btnW = myBttn.frame.size.width; 
CGFloat btnH = myBttn.frame.size.height; 
//get lesser button dimension 
CGFloat minBtn=btnW; 
if (btnW>btnH) { 
    minBtn=btnH; 
} 
//calculate scale using greater image dimension 
CGFloat scl=imgH/minBtn; 
if (imgW>imgH) { 
    scl=imgW/minBtn; 
} 
//scale image 
UIImage *scaledImage = [UIImage imageWithCGImage:[img CGImage] scale:(img.scale * scl) orientation:(img.imageOrientation)]; 
//clean up 
UIGraphicsEndImageContext(); 
//set it on a button 
[myBttn setImage:scaledImage forState:UIControlStateNormal]; 
-1

这是简单的:

ImageBn.imageView?.contentMode = .scaleAspectFit 
    ImageBn.setImage(chosenImage, for: .normal)