Josh Earl Josh Earl - 4 months ago 35
iOS Question

Resizing a UILabel to accomodate insets

I'm building a screen to scan barcodes, and I need to put a translucent screen behind some

UILabels
to improve visibility against light backgrounds.

Here's what the screen looks like now:

enter image description here

I'm setting the background color on the
UILabel
to get the translucent boxes. I've also created a custom
UILabel
subclass to allow me to set some padding between the edge of the
UILabel
and the text using this approach.

As you can see in the screen above, the
UILabel
doesn't resize correctly to take the padding into account. The "padding" just shifts the text over without changing the width of the label, causing the text to truncate.

Both of these labels will contain text of arbitrary lengths, and I really need the
UILabel
to dynamically resize.

What
UILabel
method can I override to increase the width of the label and factor in the padding?

Answer

Here's a label class that calculates sizes correctly.

By calculating the proper textRect all of the sizeToFit and auto layout stuff works as expected. The trick is to first subtract the insets, then calculate the original label bounds, and finally to add the insets again.

Swift 3

Code on github

Swift 2

import UIKit

class NRLabel : UILabel {

    var textInsets: UIEdgeInsets = UIEdgeInsetsZero

    override func textRectForBounds(bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect {
        var rect = textInsets.apply(bounds)
        rect = super.textRectForBounds(rect, limitedToNumberOfLines: numberOfLines)
        return textInsets.inverse.apply(rect)
    }

    override func drawTextInRect(rect: CGRect) {
        super.drawTextInRect(textInsets.apply(rect))
    }

}

extension UIEdgeInsets {
    var inverse: UIEdgeInsets {
        return UIEdgeInsets(top: -top, left: -left, bottom: -bottom, right: -right)
    }
    func apply(rect: CGRect) -> CGRect {
        return UIEdgeInsetsInsetRect(rect, self)
    }
}

ObjC

Code on github

Disclaimer:

Code is in the public domain. Do as you please.

Comments