web-dev-qa-db-ja.com

自動レイアウト-UIButtonの固有のサイズにはタイトルのインセットが含まれません

自動レイアウトを使用してUIButtonを配置している場合、そのサイズはコンテンツに合わせてうまく調整されます。

イメージをbutton.imageとして設定すると、本質的なサイズが再びこれを説明しているようです。

ただし、ボタンのtitleEdgeInsetsを微調整すると、レイアウトはこれを考慮せず、代わりにボタンのタイトルを切り捨てます。

ボタンの固有の幅がインセットを説明することを確認するにはどうすればよいですか?

enter image description here

編集:

私は次を使用しています:

[self.backButton setTitleEdgeInsets:UIEdgeInsetsMake(0, 5, 0, 0)];

目標は、画像とテキストを分離することです。

171
Ben Packard

これを解決するには、メソッドをオーバーライドしたり、任意の幅の制約を設定したりする必要はありません。次のように、Interface Builderですべて実行できます。

  • 固有のボタンの幅は、タイトルの幅にアイコンの幅に加えて左右を加えたものですcontent Edge insets。

  • ボタンに画像とテキストの両方がある場合、ボタンはグループとして中央に配置され、間にパディングはありません。

  • 左のコンテンツインセットを追加すると、テキスト+アイコンではなく、テキストを基準にして計算されます。

  • 負の左画像インセットを設定すると、画像は左に引き出されますが、ボタン全体の幅は影響を受けません。

  • 負の左画像インセットを設定すると、実際のレイアウトではその半分の値が使用されます。したがって、-20ポイント左インセットを取得するには、Interface Builderで-40ポイント左インセット値を使用する必要があります。

したがって、目的の左インセットandアイコンとテキストの間の内側のパディングの両方にスペースを作成するのに十分な大きさの左コンテンツインセットを提供し、必要なパディングの量を2倍にしてアイコンを左にシフトしますアイコンとテキストの間。結果は、左右のコンテンツインセットが等しいボタンと、グループとして中央に配置されたテキストとアイコンのペアで、それらの間に特定の量のパディングがあります。

いくつかの値の例:

// Produces a button with the layout:
// |-20-icon-10-text-20-|
// AutoLayout intrinsic width works as you'd desire.
button.contentEdgeInsets = UIEdgeInsetsMake(10, 30, 10, 20)
button.imageEdgeInsets = UIEdgeInsetsMake(0, -20, 0, 0)
166
jaredsinclair

ネガティブとポジティブのタイトルとコンテンツインセットを組み合わせて使用​​することにより、これをInterface Builderで(コードを記述せずに)動作させることができます。

enter image description here

Update:Xcode 7には、Rightに負の値を入力できないバグがありますフィールドを挿入しますが、その隣のステッパーコントロールを使用して値を減らすことができます。 (スチュアートに感謝)

これを行うと、画像とタイトルの間に8ptのスペースが追加され、ボタンの固有の幅が同じ量だけ増加します。このような:

enter image description here

187
n.Drake

UIViewでintrinsicContentSizeメソッドをオーバーライドしないのはなぜですか?例えば:

- (CGSize) intrinsicContentSize
{
    CGSize s = [super intrinsicContentSize];

    return CGSizeMake(s.width + self.titleEdgeInsets.left + self.titleEdgeInsets.right,
                      s.height + self.titleEdgeInsets.top + self.titleEdgeInsets.bottom);
}

これにより、ボタンのサイズを大きくしてインセットを許可し、全文を表示する必要があることを自動レイアウトシステムに伝える必要があります。私は自分のコンピューターにいないので、これをテストしていません。

92
Maarten

インセットの設定方法を指定していないので、同じ効果が得られるので、titleEdgeInsetsを使用していると推測します。代わりにcontentEdgeInsetsを使用すると、正常に機能します。

- (IBAction)ChangeTitle:(UIButton *)sender {
    self.button.contentEdgeInsets = UIEdgeInsetsMake(0,20,0,20);
    [self.button setTitle:@"Long Long Title" forState:UIControlStateNormal];
}
83
rdelmar

Swiftの場合、これが機能しました。

extension UIButton {
    override open var intrinsicContentSize: CGSize {
        let intrinsicContentSize = super.intrinsicContentSize

        let adjustedWidth = intrinsicContentSize.width + titleEdgeInsets.left + titleEdgeInsets.right
        let adjustedHeight = intrinsicContentSize.height + titleEdgeInsets.top + titleEdgeInsets.bottom

        return CGSize(width: adjustedWidth, height: adjustedHeight)
    }
}

ラブ・ユー・スウィフト

19
pegpeg

このスレッドは少し古いですが、私は自分でこれに出くわし、ネガティブインセットを使用してそれを解決することができました。たとえば、ここで目的のパディング値に置き換えます。

UIButton* myButton = [[UIButton alloc] init];
// setup some autolayout constraints here
myButton.titleEdgeInsets = UIEdgeInsetsMake(-desiredBottomPadding,
                                            -desiredRightPadding,
                                            -desiredTopPadding,
                                            -desiredLeftPadding);

適切な自動レイアウト制約と組み合わせると、画像とテキストを含む自動サイズ変更ボタンになります! desiredLeftPaddingを10に設定して以下に示します。

Button with image and short text

Button with image and long text

ボタンの実際のフレームはラベルを取り囲んでいないことがわかります(ラベルが境界の外側で10ポイント右にシフトしているため)が、テキストと画像の間に10ポイントのパディングを達成しました。

18
Brian Gerstle

Swift 3の場合、 pegpeg の回答に基づきます:

extension UIButton {

    override open var intrinsicContentSize: CGSize {

        let intrinsicContentSize = super.intrinsicContentSize

        let adjustedWidth = intrinsicContentSize.width + titleEdgeInsets.left + titleEdgeInsets.right
        let adjustedHeight = intrinsicContentSize.height + titleEdgeInsets.top + titleEdgeInsets.bottom

        return CGSize(width: adjustedWidth, height: adjustedHeight)

    }

}
9
TheoK

上記のすべてがiOS 9 +で機能しませんでした。

  • 幅の制約を追加します(ボタンにテキストがない場合の最小幅。テキストが提供されている場合、ボタンは自動的に拡大縮小します)
  • 関係を「より大きい」または「等しい」に設定します

enter image description here

ボタンの周囲に境界線を追加するには、次のメソッドを使用します。

button.contentEdgeInsets = UIEdgeInsetsMake(0,20,0,20);
6
Oritm

UIButtonアイコンとラベルの間に5ポイントのスペースを追加したかった。これは私がそれを達成した方法です:

UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeCustom];
// more button config etc
infoButton.contentEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 5);
infoButton.titleEdgeInsets = UIEdgeInsetsMake(0, 5, 0, -5);

ContentEdgeInsets、titleEdgeInsets、およびimageEdgeInsetsが相互に関連する方法では、各インセットから少しずつやり取りする必要があります。そのため、タイトルの左側にインセットを追加する場合は、右側に負のインセットを追加し、コンテンツの右側に(正のインセットを介して)スペースを追加する必要があります。

タイトルインセットのシフトに合わせて適切なコンテンツインセットを追加することにより、テキストがボタンの境界の外に出ることはありません。

5
orj

このオプションは、インターフェイスビルダーでも使用できます。差し込み図を参照してください。左右を3に設定します。まるでチャームのように機能します。

Interface builder screenshot

3
zeiteisen

私が使用する解決策は、ボタンに幅の制約を追加することです。次に、初期化のどこかで、テキストを設定した後、次のように幅の制約を更新します。

self.buttonWidthConstraint.constant = self.shareButton.intrinsicContentSize.width + 8;

8は、インセットが何であるかです。

1
Bob Spryn

sizeToFit()を呼び出すと、contentEdgeInsetが有効になります

 extension UIButton {

              open override func draw(_ rect: CGRect) { 
                    self.contentEdgeInsets = UIEdgeInsets(top: 10,left: 40,bottom: 10,right: 40)
                    self.sizeToFit()
              }
           }
0
Ali