web-dev-qa-db-ja.com

ボタンの背景画像が伸びないようにするにはどうすればよいですか?

UIButtonTypeCustom UIButtonを、ボタンのフレームより小さい背景画像を持つUIViewに割り当てています。画像が小さくなる理由は、UIButtonの「ターゲット領域」をさらに追加しようとしているためです。ただし、画像は単に画像のサイズではなく、フレームのフルサイズにスケーリングされています。

UIButtonとUIButtonのimageView contentModeプロパティを「UIViewContentModeScaleAspectFit」に設定しようとしましたが、運が悪く、画像が引き伸ばされたままになります。

私がプログラムでやろうとしていることを行う方法はありますか?

前もって感謝します!

51
Raphael Caixeta

多くの人々は、ボタンの画像に関してあなたがするのと同じ間違いを犯し、ボタンを期待通りに動作させようとフープを飛び越えます。これをきっぱりとクリアしましょう:

A UIButtonには、表示できる2種類の画像(前景画像と背景画像)があります。ボタンの背景画像は、ボタンの背景テクスチャに置き換わるものです。そのため、背景全体を埋めるためにストレッチすることは理にかなっています。ただし、ボタンの前景画像は、テキストと一緒に表示される場合とされない場合があるアイコンであると予想されます。伸縮しません。 Itmayフレームは画像よりも小さいですが、伸びません。 Interface Builderのコントロールの配置プロパティを使用して、前景画像の配置を設定することもできます。

ボタンの前景と背景の画像は、次のようなコードで設定できます。

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

// not stretchy
[self setImage:forgroundImage forState:UIControlStateNormal]; 
124
memmons

背景のimageViewにアクセスできませんが、完全に回避策があります:

[〜#〜] edit [〜#〜]:元々投稿したものよりもさらに良い回避策があります。任意の色から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. 画像ビューを作成する
  2. コンテンツモードとフレームを設定する
  3. また、認識可能なタグを設定して、画面が回転したときにボタンのサブビューでカスタムimageViewを簡単に見つけてフレームをリセットできるようにします
  4. サブビューとしてボタンに追加します
  5. ボタンの正面のimageViewを前面に移動します。これにより、カスタムimageViewが重ならないようにします。

ボタンを回転する必要がある場合、タグでimageViewを見つけてフレームをリセットします。

UIImageView *bgImageView = (UIImageView *)[button viewWithTag:99];
[bgImageView setFrame:CGRectMake(0, 0, newWidth, newHeight)];
8
Zoltán Matók

この問題にもつまずいた。

プログラムで画像を追加することは、メモンが徹底的に説明したように、助けにはなりませんでした:(

ボタン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
Boris Gafurov

おそらくボタンのタイトルインセットを使用する最もクリーンで簡単な方法。

画像をボタン画像として設定してから、左のタイトルインセットを変更して画像の幅を引いたものに合わせます:

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

これにより、画像が左に追加される前の位置にテキストが戻ります。この値を使用して、ボタンにパディングを追加することもできます。

1
AntonyG

誰かを助けるかもしれない

button.subviews.first?.contentMode = .scaleAspectFit
0

もう1つの考慮事項は、BaseLine制約です。ボタンにこの制約が設定されている場合(レイアウト上の複数のコントロールを通る水平線または垂直線として示されている)、下にあるボタンコントロールを引き伸ばさずに画像が引き伸ばされます。ボタンが他の方法で適切に制約されている場合(リーディング/トレーリングおよび上部/下部スペースなど)、BaseLine制約を削除してもレイアウトに影響はありませんが、前景画像は下にあるボタンの形状に合わせて適切に拡大縮小できます。

0
Epsilon3

最も簡単な解決策は、UIImageのresizableImageWithCapInsetsメソッドを使用することだと思います。 UIEdgeInsetsMakeを使用して、空きスペースを構成します。

0
MacMark