1. ホーム
  2. iphone

[解決済み】UIButtonのテキストと画像をimageEdgeInsetsとtitleEdgeInsetsで整列させる。

2022-04-04 09:42:36

質問

2行のテキストの左側にアイコンを置きたいのですが、画像とテキストの始まりの間に2~3ピクセル程度のスペースが必要です。コントロール自体は水平に中央揃え(Interface Builderで設定)です。

ボタンはこのような感じになります。

|                  |
|[Image] Add To    |
|        Favorites |

contentEdgeInset、imageEdgeInsets、titleEdgeInsetsで設定しようとしているのですが、うまくいきません。負の値はエッジを拡大し、正の値はエッジを縮小して中央に近づけることは理解しています。

試してみました。

[button setTitleEdgeInsets:UIEdgeInsetsMake(0, -image.size.width, 0, 0)];
[button setImageEdgeInsets:UIEdgeInsetsMake(0, button.titleLabel.bounds.size.width, 0, 0)];

が、これでは正しく表示されません。値を微調整していますが、例えば左の挿入値を-5から-10にしても、期待通りの動きにはならないようです。-10だとテキストが左に寄ってしまうので、-5だと左側から半分くらいに寄ってしまうと思ったのですが、そうではありません。

インセットのロジックは?画像の配置や関連用語に詳しくないのですが。

このSOの質問を参考にしたのですが、何か私の価値観がおかしいような気がします。 UIButton: imageEdgeInsets と titleEdgeInsets を使って画像とテキストを中央揃えする方法は?

どのように解決するのですか?

のドキュメントに同意します。 imageEdgeInsetstitleEdgeInsets の方が良いのですが、試行錯誤することなく正しい位置決めをする方法を考えました。

一般的な考え方は、こちらの この質問 しかし、それはテキストと画像の両方を中央揃えにしたい場合の話です。 画像とテキストを個別に中央寄せにするのではなく、画像とテキストを一体として中央寄せにしたいのです。 これは実際、UIButtonがすでに行っていることなので、単にスペーシングを調整する必要があります。

CGFloat spacing = 10; // the amount of spacing to appear between image and title
tabBtn.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, spacing);
tabBtn.titleEdgeInsets = UIEdgeInsetsMake(0, spacing, 0, 0);

また、使いやすいようにUIButtonのカテゴリにしました。

UIButton+Position.h

@interface UIButton(ImageTitleCentering)

-(void) centerButtonAndImageWithSpacing:(CGFloat)spacing;

@end

UIButton+Position.m

@implementation UIButton(ImageTitleCentering)

-(void) centerButtonAndImageWithSpacing:(CGFloat)spacing {
    self.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, spacing);
    self.titleEdgeInsets = UIEdgeInsetsMake(0, spacing, 0, 0);
}

@end

だから、今私がしなければならないことは

[button centerButtonAndImageWithSpacing:10];

そして、毎回必要なものを手に入れることができるのです。 もうエッジのインセットを手動でいじる必要はありません。

EDIT:画像とテキストの入れ替え

コメント中の@Javalさんへの返答

これと同じ仕組みで、画像とテキストを入れ替えることができます。入れ替えを行うには、単純に負のスペーシングを使用し、テキストと画像の幅も含める。これには、フレームが既知でレイアウトが実行されていることが必要です。

[self.view layoutIfNeeded];
CGFloat flippedSpacing = -(desiredSpacing + button.currentImage.size.width + button.titleLabel.frame.size.width);
[button centerButtonAndImageWithSpacing:flippedSpacing];

もちろん、あなたはこのための素晴らしいメソッドを作りたいと思うでしょうし、第2のカテゴリーメソッドを追加する可能性もありますが、これは読者のための練習として残されています。