UIButtonがiPhoneのアスペクトフィットに移動しない


105

私はいくつかのUIButtonを持っていますが、IBではそれらはAspect Fitに設定されていますが、何らかの理由で常に伸縮しています。他に設定する必要があるものはありますか?私はすべての異なる表示モードを試しましたが、どれも機能せず、すべて伸びています。


@Werner Altesischerの答えは正しいものです。適切な変更を行います。
Harshit Gupta 2014

1
@marty背景画像または画像を設定していますか?背景画像はサポートしていません。画像のみです。
ファンボエロ2015

回答:


45

私は以前にその問題を抱えていました。設定が実際に機能するUIImageViewに画像を配置し、その上にcontentMode透明なカスタムを配置UIButtonすることで解決しました。

編集:この答えは時代遅れです。最新バージョンのiOSでの正しい答えについては、@ Werner Altewischerの答えを参照してください。


はい、試してみましたが、画像に再フィットするボタンを取得できません
marty

この手法でボタンの状態をどのように管理しますか?「強調表示された」などのユーザーインタラクションに応答するのは悪夢のようです。
SooDesuNe 2012年

3
これは、この質問に回答した2.5年前の正しい方法だったかもしれませんが、UIButtonの内部ImageViewを編集してコンテンツモードを設定できるようになりました。@Werner Altewischerによる回答をご覧ください
Steve Haley

233

解決策はcontentMode、のimageViewプロパティをに設定することUIButtonです。これUIButtonを機能させるには、カスタムタイプでを作成する必要があります(それ以外の場合nilは、このプロパティに対して返されます)。


67
これは私にとっては[button.imageView setContentMode:UIViewContentModeScaleAspectFit];
うまくいき

2
これも機能しますが、adjustsImageWhenHighlighted = YESを設定すると、ボタンをタップしたときに画像が再び引き伸ばされます。
cduck

1
adjustsImageのストレッチはiOS 6で削除されました。–
Ben Flynn

3
iOS 8では、これは実際には機能しません。元の答え(imageViewを透明なボタンの後ろに配置)が最適です。
user1416564

3
Swift du jour:button.imageView!.contentMode = UIViewContentMode.scaleAspectFit
Nestor

57

この方法は私にとってはうまくいきました。

XIBボタンやセットを選択user defined runtime attributes

  • キーパス: self.imageView.contentMode
  • タイプ: Number
  • 値: 1

ソリューションをより明確に表示するには、ここをクリックしてください

enumは使用できないため、数値を使用しています。ただし、UIViewContentModeScaleAspectFitは1です。


2
これにより、設計時にインターフェイスビルダーのイメージも更新されました。素晴らしいソリューション。
George Filippakos

優れたソリューション、少数のコードでチャームのように機能する列挙型は、コンテンツモードのリストアイテムに基づいています。
クロス

また、それが少し簡単にするために拡張機能を追加することができます extension UIButton { @IBInspectable var imageContentMode: Int { get {return imageView?.contentMode.rawValue ?? 0} set {imageView?.contentMode = UIViewContentMode(rawValue: newValue) ?? .scaleAspectFit} } }
Yonat

「自己」なし imageView.contentModeで私のために働いた!
by Jeevan

22

これをInterface Builderで行う場合は、ランタイム属性インスペクターを使用して、コードなしで直接設定できます。

ボタンのキーパスを「imageView.contentMode」に設定し、タイプを「Number」、値を「1」(または任意のモード)に設定します。

imageview.contentMode = 1


14

contentModeにはボタンのimageViewを使用します。ボタン自体には直接ありません。

homeButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
homeButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
homeButton.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
[homeButton setImage:[UIImage imageNamed:kPNGLogo] forState:UIControlStateNormal];

6

UIImageViewボタンの後ろに画像を配置すると、組み込みの機能が失われます。UIButtonadjustsImageWhenHighlightedadjustsImageWhenDisabled、やなどクラスの失われます。もちろん、さまざまな状態にさまざまな画像を設定できます(これを自分で行う必要はありません)。

すべての制御状態で画像を展開しない場合はimageWithCGImage:scale:orientation、次のメソッドのように、1つの方法は、を使用して画像を取得することです。

- (UIImage *) getScaledImage:(UIImage *)img insideButton:(UIButton *)btn {

    // Check which dimension (width or height) to pay respect to and
    // calculate the scale factor
    CGFloat imgRatio = img.size.width / img.size.height, 
            btnRatio = btn.frame.size.width / btn.frame.size.height,
            scaleFactor = (imgRatio > btnRatio 
                           ? img.size.width / btn.frame.size.width
                           : img.size.height / btn.frame.size.height;

    // Create image using scale factor
    UIImage *scaledImg = [UIImage imageWithCGImage:[img CGImage]
                                             scale:scaleFactor
                                       orientation:UIImageOrientationUp];
    return scaledImg;
}

これを実装するには、次のように記述します。

UIImage *scaledImg = [self getScaledImage:myBtnImg insideButton:myBtn];
[myBtn setImage:scaledImg forState:UIControlStateNormal];

これにより、すべての制御状態で画像が拡大するのを防ぐことができます。うまくいきましたが、うまくいかない場合はお知らせください。

注:ここでは、に関連する問題に取り組んでいますUIButtonが、insideButton:そうでないinsideView:場合もあるでしょう。


6

しばらく前にこの問題がありました。私が抱えていた問題は、この効果を限られたバックグラウンドのUIButtonに適用しようとしていたため、簡単に調整できないことでした。

トリックは、それを単なる画像として設定してから、@ ayreguitarの手法を適用することです。

UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];
[myButton setContentMode:UIViewContentModeScaleAspectFill];
[myButton setImage:@"myImage.png" forState:UIControlStateNormal];



4

いくつかの異なる答えを1つのソリューションに結合します。カスタムタイプのボタンを作成し、ボタンのimageView contentModeプロパティを設定し、ボタンの画像を設定します(背景画像ではなく、塗りつぶすためにスケーリングされます)。

//Objective-C:
UIImage *image = [UIImage imageNamed:"myImageName.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:image forState:UIControlStateNormal];
button.imageView.contentMode = UIViewContentModeScaleAspectFit;

//Swift:
let image = UIImage(named: "myImageName.png")
let button = UIButton(type: .custom)
button.imageView?.contentMode = .scaleAspectFit
button.setImage(image, for: .normal)

3
btn.imageView.contentMode = UIViewContentModeScaleAspectFit;

このコードスニペットは問題を解決する可能性がありますが、説明を含めると、投稿の品質を向上させるのに役立ちます。あなたは将来の読者のための質問に答えていることを覚えておいてください、そしてそれらの人々はあなたのコード提案の理由を知らないかもしれません。- レビューより
Ferrybig

2

この回答は@WernerAltewischerの回答に基づいています

ボタンをIBOutletに接続してコードを実行しないようにするために、UIButtonのクラスをサブクラス化しました。

// .h
@interface UIButtonWithImageAspectFit : UIButton
@end

// .m
@implementation UIButtonWithImageAspectFit

- (void) awakeFromNib {
    [self.imageView setContentMode:UIViewContentModeScaleAspectFit];
}

@end



次に、xibにカスタムボタンを作成し、その画像(背景画像ではない)を設定します。

UIButtonWithImageAspectFit:画像の作成と設定


次に、そのクラスを設定します。

UIButtonWithImageAspectFit:カスタムクラスを設定します

完了です! ボタンの画像のアスペクトフィットの
代わりに
画像のアスペクトフィットがないUIButton
、期待どおりにフィットします。
画像アスペクトフィットのUIButton


2

ios 12.コンテンツAlignmentも追加する必要があります

class FitButton: UIButton {

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)


    }

    override func layoutSubviews() {
        self.imageView?.contentMode = .scaleAspectFill
        self.contentHorizontalAlignment = .fill
        self.contentVerticalAlignment = .fill
        super.layoutSubviews()


    }

}

1

画像が比例してサイズ変更されないという問題があったため、修正方法はエッジインセットを使用していました。

fooButton.contentEdgeInsets = UIEdgeInsetsMake(10, 15, 10, 15);

1

UIViewコンテンツモードは、対応するCALayerの「コンテンツ」に適用されます。コンテンツが対応するUIImageViewに設定されているため、これはsで機能します。CALayerCGImage

drawRect: 最終的には、レイヤーコンテンツにレンダリングされます。

カスタムUIButton(私の知る限り)にはコンテンツがありません(角丸四角形のボタンはコンテンツを使用してレンダリングされる場合があります)。ボタンにはサブビューがあります。背景UIImageView、画像UIImageView、タイトルUILabelです。contentModeサブビューにonを設定すると、望みどおりの結果が得られますが、UIButtonビューの階層をいじるのは少々ノーノーです。


1

変更UIButton.imageView.contentModeしてもうまくいきません。
画像を「背景」プロパティに設定することで問題を解決しました。
必要に応じて比率制約を追加できます


1

これは他の多くの回答と重複していますが、私にとっての解決策は

  • セットcontentModeのをUIImageViewボタンにするために.ScaleAspectFit-のいずれかInterface Builderでの「ランタイムユーザー定義属性」を行うことができます(。すなわちself.imageView.contentMode、数、1)またはでUIButtonサブクラス;
  • 「サブビューの自動サイズ変更」を無効にします。
  • 「エッジ」を「画像」に設定し、「インセット」の適切な「上」および「下」の値を設定します(これは、私のように、PDFを画像として使用した場合にのみ必要になる場合があります)。

0

上記のようにimageWithCGImageを使用できます(ただし、括弧が欠けていません)。

また... 4.0以外の数百万の電話は、そのコードではまったく機能しません。



0

@Guillaumeと同様に、UIButtonのサブクラスをSwift-Fileとして作成しました。次に、インターフェイスビルダーでカスタムクラスを設定します。

インターフェースビルダー

そしてここにSwiftファイル:

import UIKit

class TRAspectButton : UIButton {
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.imageView?.contentMode = .ScaleAspectFit
    }
}

-1

同じ問題が発生しましたが、機能しませんでした(おそらく、SDKのバグです)。

最終的には、回避策としてUIImageView、ボタンの後ろに配置し、それに必要なオプションを設定してから、そのUIButton上に空白を配置しました。


7
ここに反響はありますか?;-)
Dan Ray
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.