Home > Software design >  How to indent text in a label? Swift, UIKit
How to indent text in a label? Swift, UIKit

Time:02-04

I have a text in a label right aligned. The label is in a dynamic table cell. But the text is very close to the right edge of the label and does not look presentable. It looks something like this:

1234.5|

Update: How it looks on the screen. 0 is adjacent to the right side of the screen enter image description here

I would like to move the text a little bit from the right edge to make it look like this:

1234.5--|

In the text field, I use a custom class for this and override the following functions:

private let padding = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 20)

override func textRect(forBounds bounds: CGRect) -> CGRect {
    bounds.inset(by: padding)
}

override func editingRect(forBounds bounds: CGRect) -> CGRect {
    bounds.inset(by: padding)
}

The label has an UIEdgeInsets object too. But I could not find functions similar to the functions of techRect and EditingRect on the label.

It seems to me that the label should have such functions. Maybe they are called differently. But I have not yet been able to find them in the documentation and Google search has not helped either.

Maybe someone has already solved such a problem and could suggest either the solution itself or in which direction to look. Any ideas are welcome. I really appreciate your help.

CodePudding user response:

You could use a simple UILabel subclass with edge insets, like this:

class PaddedLabel: UILabel {
    var padding: UIEdgeInsets = .zero
    override func drawText(in rect: CGRect) {
        super.drawText(in: rect.inset(by: padding))
    }
    override var intrinsicContentSize : CGSize {
        let sz = super.intrinsicContentSize
        return CGSize(width: sz.width   padding.left   padding.right, height: sz.height   padding.top   padding.bottom)
    }
}

Then set your custom "padding" like this:

label.padding = UIEdgeInsets(top: 0.0, left: 20.0, bottom: 0.0, right: 20.0)

Quick example:

class PaddedTestVC: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let defaultLabel = UILabel()
        let paddedLabel = PaddedLabel()
        
        [defaultLabel, paddedLabel].forEach { v in
            v.backgroundColor = .green
            v.text = "Test Text"
            v.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(v)
        }
        
        let g = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            
            defaultLabel.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0),
            defaultLabel.centerXAnchor.constraint(equalTo: g.centerXAnchor),
            
            paddedLabel.topAnchor.constraint(equalTo: defaultLabel.bottomAnchor, constant: 40.0),
            paddedLabel.centerXAnchor.constraint(equalTo: g.centerXAnchor),
            
        ])
        
        paddedLabel.padding = UIEdgeInsets(top: 12.0, left: 20.0, bottom: 12.0, right: 20.0)
    }
    
}

The top label is a default UILabel the bottom label is a PaddedLabel - the only difference is the .padding:

enter image description here

A better option (in my view) would be to constrain your stack view to the margins of the cell's contentView - that way you get the defined margins (top/bottom and sides) spacing for the device and traits.

  • Related