UILabel text margin

Viewed 307613

I'm looking to set the left inset/margin of a UILabel and can't find a method to do so. The label has a background set so just changing its origin won't do the trick. It would be ideal to inset the text by 10px or so on the left hand side.

38 Answers

I didn't find the suggestion to use UIButton in the answers above. So I will try to prove that this is a good choice.

button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8)

In my situation using UIButton was the best solution because:

  • I had a simple single-line text
  • I didn't want to use UIView as a container for UILabel (i.e. I wanted to simplify math calculations for Autolayout in my cell)
  • I didn't want to use NSParagraphStyle (because tailIndent works incorrect with Autolayout – width of UILabel is smaller than expected)
  • I didn't want to use UITextView (because of possible side effects)
  • I didn't want to subclass UILabel (less code fewer bugs)

That's why using the contentEdgeInsets from UIButton in my situation became the easiest way to add text margins.

Hope this will help someone.

Swift 4 version of blyabtroi solution

let leadingMargin: CGFloat = 10
let trailingMargin: CGFloat = 10

let style = NSMutableParagraphStyle()
style.alignment = .justified
style.firstLineHeadIndent = leadingMargin
style.headIndent = leadingMargin
style.tailIndent = trailingMargin

label.attributedText = NSAttributedString(string: "Label with margins", 
                                          attributes: [NSAttributedStringKey.paragraphStyle: style])

Swift 3 & AutoLayout compatible version:

class InsetLabel: UILabel {

    var insets = UIEdgeInsets()

    convenience init(insets: UIEdgeInsets) {
        self.init(frame: CGRect.zero)
        self.insets = insets
    }

    convenience init(dx: CGFloat, dy: CGFloat) {
        let insets = UIEdgeInsets(top: dy, left: dx, bottom: dy, right: dx)
        self.init(insets: insets)
    }

    override func drawText(in rect: CGRect) {
        super.drawText(in: UIEdgeInsetsInsetRect(rect, insets))
    }

    override var intrinsicContentSize: CGSize  {
        var size = super.intrinsicContentSize
        size.width += insets.left + insets.right
        size.height += insets.top + insets.bottom
        return size
    }
}

This is the easiest solution I found for this:

Swift 4

class CustomLabel: UILabel{
    override func drawText(in rect: CGRect) {
        super.drawText(in: rect.inset(by: UIEdgeInsets.init(top: 10, left: 10, bottom: 10, right: 10)))
    }
}

Make sure you set your labels to the CustomLabel class in code as well as in storyboard.

If label is created programmatically, padding can be calculated using the sizeThatFits method. If using more than one line, the text will be line broken at the max width value.

let text = UILabel()
let padding = 10
text.layer.cornerRadius = 5
text.layer.masksToBounds = true
text.text = "Hello"
text.font = UIFont(name: text.font.fontName, size: 18)
text.textAlignment = NSTextAlignment.center
text.numberOfLines = 1

let maxSize = CGSize(width: 100, height: 100)
var size = text.sizeThatFits(maxSize)
size.width = size.width + padding * 2
size.height = size.height + padding * 2
text.frame = CGRect(origin: CGPoint(x: 0, y: 0), size: size)

I had solved it using xcode builder (but surely this could be achieved with swift using constraints):

Just create a UIView of the relevant size And add a child of type UILabel to that view

and there you go, you have padding :)

xcode builder solution

You need to calculate UILabel size when you put insets. It can have different number of lines because of text alignment, line break mode.

override func drawText(in rect: CGRect) {

    let size = self.sizeThatFits(UIEdgeInsetsInsetRect(rect, insets).size);
    super.drawText(in: CGRect.init(origin: CGPoint.init(x: insets.left, y: insets.top), size: size));
}

override var intrinsicContentSize: CGSize {

    var size = super.intrinsicContentSize;

    if text == nil || text?.count == 0 {
        return size;
    }

    size = self.sizeThatFits(UIEdgeInsetsInsetRect(CGRect.init(origin: CGPoint.zero, size: size), insets).size);
    size.width  += self.insets.left + self.insets.right;
    size.height += self.insets.top + self.insets.bottom;

    return size;
}

try iEun/InsetLabel

A lot of these answers are complicated. In some cases, that's necessary. However, if you're reading this, your label has no left/right margin, and you just want a little padding, here's the whole solution:

Step 1: Add spaces at the end (literally, hit the spacebar a few times)

Step 2: Set the text alignment of the label to centered

Done

Related