2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Swift】複数行のUILabelの余白を設定する:上下左右

Posted at

はじめに

環境は
・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で半自動化はできるはず。

最後に

他に良い方法があったら教えてください!

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?