The environment is ・ Xcode 11.6 ・ Swift 5 Will be.
There are times when you want to set the label margins (padding), right?
For example, in the case of textView, use textContainerInset
, and in the case of UIButton, use contentEdgeInsets
, etc., and I think that it can be set relatively easily.
But with UILabel, it's a bit annoying, especially with multi-line text.
Especially for the horizontal margins, ʻattributedText` may solve it neatly. The following is an example.
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
In the vertical direction, you can specify the line spacing and line height, but it's a shame that you can't set the margins directly. However, if the text is one line, you can set the line height and font size well to effectively control the top and bottom margins.
It's a common way to search, but if you create a custom Label that inherits UILabel as shown below, it will usually be solved.
You can set the top, bottom, left, and right margins properly.
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
}
}
You don't have to have sizeThatFits (_ size: CGSize)
here, but if you do, it will automatically adjust to the size including the margins when you do sizeToFit ()
, so I'm grateful.
Of course, if you don't want to include margins in sizeToFit ()
, don't override it.
If you have a problem that doesn't work, the last resort is probably
UILabel( ) in UIView( )
As a label, you can treat the parent view as a label (or button) with margins by placing it at any position in the parent view after making it blank with the usual sizeToFit ()
.
In this case you have to specify the size of the parent view here, but you should be able to semi-automate with sizeToFit ()
+ ʻAutoLayout`.
Please let me know if there is another good way!