UIButtonのInsetsがうまく設定できなかったので調べてみた


UIButtonにpaddingを設定して表示したかったので以下のようなコードを書いたところ、文字サイズを全て固定で指定しているのにサイズがバラバラになってしまうという現象が発生しました。

btn.layer.cornerRadius = 16
btn.backgroundColor = UIColor.gray
btn.titleLabel?.font = UIFont.systemFont(ofSize: 28.0)
btn.titleEdgeInsets = UIEdgeInsetsMake(5.0, 7.0, 5.0, 7.0)
btn.titleLabel?.adjustsFontSizeToFitWidth = true

titleEdgeInsetsを指定

最初、日本語だけこのようなことになるのではないかと思いましたがそんなこともなさそうでした。文字数には影響されているようです。
ちなみにtitleEdgeInsetsを指定しなかったら文字サイズがバラバラになることはありませんでした。

titleEdgeInsetsを指定しない

UIButtonクラスをよく見てみると、もう一つInsetsを指定できるプロパティがありました。それがcontentEdgeInsetsです。試しにtitleEdgeInsetsではなくcontentEdgeInsetsにUIEdgeInsetsMake(5, 7, 5, 7)を指定してみると以下のような表示になりました。

contentEdgeInsetsを指定

Insetsが正しく設定されているようです。

このような現象について書かれている記事はないかと探したところ、SnapKitのissueが見つかりました。そのissueでは「AutoLayoutでは残念ながらtitleEdgeInsetsは効かない。でもcontentEdgeInsetsなら実現できる。また、別のやり方としてintrinsicContentSizeを使うというやり方もある。」というやり取りがありました。結局このissueを立てた人はtitleEdgeInsetsの一部にマイナスの値を指定し、不足分をcontentEdgeInsetsの方で補充したようです。この部分についてはあるstackoverflowの回答を見ると言っていることがより理解できます。

ということでUIButtonでInsetがうまくいかない時はcontentEdgeInsetsの利用を検討してみるとうまくいくかもしれません。