Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
12 views
in Technique[技术] by (71.8m points)

ios - Text padding on UILabel

Here, I am trying to have a label with some padding (left, right, top and bottom) around the text. This issue has related post on SOF and after reading a few of them, I tried using a solution proposed here:

This is the code for my subclassing UILabel:

import UIKit

class LuxLabel: UILabel {
    //let padding: UIEdgeInsets
    var padding: UIEdgeInsets = UIEdgeInsets.zero {
        didSet {
            self.invalidateIntrinsicContentSize()
        }
    }    

    // Create a new PaddingLabel instance programamtically with the desired insets
    required init(padding: UIEdgeInsets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10)) {
        self.padding = padding
        super.init(frame: CGRect.zero)
    }

    // Create a new PaddingLabel instance programamtically with default insets
    override init(frame: CGRect) {
        padding = UIEdgeInsets.zero // set desired insets value according to your needs
        super.init(frame: frame)
    }

    // Create a new PaddingLabel instance from Storyboard with default insets
    required init?(coder aDecoder: NSCoder) {
        padding = UIEdgeInsets.zero // set desired insets value according to your needs
        super.init(coder: aDecoder)
    }

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

    // Override `intrinsicContentSize` property for Auto layout code
    override var intrinsicContentSize: CGSize {
        let superContentSize = super.intrinsicContentSize
        let width = superContentSize.width + padding.left + padding.right
        let heigth = superContentSize.height + padding.top + padding.bottom
        return CGSize(width: width, height: heigth)
    }
}

It is based on PaddingLabel (cf. the above link).

It is mostly working well, but for some reasons that I do not understand, there are cases where things go wrong and the display gets truncated.

This is an example:

The string to put on the label is:

"It has a square shape and a blue color."

The code to create the label is:

let label = LuxLabel(padding: UIEdgeInsets(top: 5, left: 10, bottom: 5, right: 10))
label.numberOfLines = 0

and this is the result:

enter image description here

If I add this line to the two above:

label.lineBreakMode = .byWordWrapping

the result is:

enter image description here

I have also set some constraints. All this works 95% of the time. Can anyone see what is the problem?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Try calling invalidateIntrinsicContentSize:

var padding: UIEdgeInsets = UIEdgeInsets.zero {
    didSet {
        self.invalidateIntrinsicContentSize()
    }
}

EDIT:

I have tried different options. If you update the frame size with the intrinsicContentSize in layoutSubviews that make the trick but I don't know if there is a better way to do it:

override func layoutSubviews() {
    super.layoutSubviews()
    self.frame.size = self.intrinsicContentSize
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...