2011-12-30 215 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)