はじめに
環境は
・Xcode 11.6
・Swift 5
になります。
ラベルの余白(パディング)を設定したいとき、ありますよね?
例えばtextViewの場合はtextContainerInset
、UIButtonの場合はcontentEdgeInsets
なんかを使って、比較的楽に設定できるかと思います。
しかしUILabelの場合は少し面倒で、複数行のテキストだと尚更。
まず試すこと
特に横方向の余白については、attributedText
できれいに解決するかも。
以下は一例。
let style = NSMutableParagraphStyle()
// horizontal setting
style.headIndent = 0
style.tailIndent = 0
// vertical setting
style.lineSpacing = 0
style.maximumLineHeight = 16
style.minimumLineHeight = 16
style.paragraphSpacingBefore = 10
style.paragraphSpacing = 30
let attr: [NSAttributedString.Key : Any] = [
.font: ...,
.paragraphStyle : style,
]
let attributedText = NSAttributedString(string: "hoge", attributes: attr)
let label = UILabel()
label.attributedText = attributedText
縦方向については、行間隔と行の高さを指定できるものの、直接余白を設定できないのが悔しい。
ただしテキストが1行の場合は、行の高さとフォントサイズをうまく設定して、実質的に上下の余白をコントロールするやり方も。
大抵はこれでオッケー
検索すればよく出てくるやり方だが、以下のようにUILabelを継承したカスタムLabelを作ってやれば、大抵は解決する。
きちんと上下左右の余白を設定できる。
class PaddingLabel: UILabel {
var padding: UIEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
override func drawText(in rect: CGRect) {
let newRect = rect.inset(by: padding)
super.drawText(in: newRect)
}
override var intrinsicContentSize: CGSize {
var contentSize = super.intrinsicContentSize
contentSize.height += padding.top + padding.bottom
contentSize.width += padding.left + padding.right
return contentSize
}
override func sizeThatFits(_ size: CGSize) -> CGSize {
var contentSize = super.sizeThatFits(size)
contentSize.width += padding.left + padding.right
contentSize.height += padding.top + padding.bottom
return contentSize
}
}
ここでsizeThatFits(_ size: CGSize)
は無くても良いが、これがあるとsizeToFit()
したときに余白を含んだ大きさで自動調整してくれるので、ありがたい。
もちろん、sizeToFit()
で余白を含めたくなければ、オーバーライドしないでおく。
最終手段
以上で解決しない問題があったら、おそらく最終手段は
UILabel( ) in UIView( )
として、ラベルは通常のsizeToFit()
で余白なしの状態にしてから親ビュー内の任意の位置に配置することによって、親ビューを余白つきのラベル(もしくはボタン)として扱える。
この場合は親ビューのサイズをこちらで指定しないといけないが、sizeToFit()
+AutoLayout
で半自動化はできるはず。
最後に
他に良い方法があったら教えてください!