Adding space/padding to a UILabel
I have tried with it on Swift 4.2, hopefully it work for you!
@IBDesignable class PaddingLabel: UILabel { @IBInspectable var topInset: CGFloat = 5.0 @IBInspectable var bottomInset: CGFloat = 5.0 @IBInspectable var leftInset: CGFloat = 7.0 @IBInspectable var rightInset: CGFloat = 7.0 override func drawText(in rect: CGRect) { let insets = UIEdgeInsets(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset) super.drawText(in: rect.inset(by: insets)) } override var intrinsicContentSize: CGSize { let size = super.intrinsicContentSize return CGSize(width: size.width + leftInset + rightInset, height: size.height + topInset + bottomInset) } override var bounds: CGRect { didSet { // ensures this works within stack views if multi-line preferredMaxLayoutWidth = bounds.width - (leftInset + rightInset) } } }
Or you can use CocoaPods here https://github.com/levantAJ/PaddingLabel
pod 'PaddingLabel', '1.2'
If you want to stick with UILabel, without subclassing it, Mundi has given you a clear solution.
If alternatively, you would be willing to avoid wrapping the UILabel with a UIView, you could use UITextView to enable the use of UIEdgeInsets (padding) or subclass UILabel to support UIEdgeInsets.
Using a UITextView would only need to provide the insets (OBJ-C):
textView.textContainerInset = UIEdgeInsetsMake(10, 0, 10, 0);
Alternative, if you subclass UILabel, an example to this approach would be overriding the drawTextInRect method
(OBJ-C)
- (void)drawTextInRect:(CGRect)uiLabelRect { UIEdgeInsets myLabelInsets = {10, 0, 10, 0}; [super drawTextInRect:UIEdgeInsetsInsetRect(uiLabelRect, myLabelInsets)];}
You could additionally provide your new subclassed UILabel with insets variables for TOP, LEFT, BOTTOM and RIGHT.
An example code could be:
In .h (OBJ-C)
float topInset, leftInset,bottomInset, rightInset;
In .m (OBJ-C)
- (void)drawTextInRect:(CGRect)uiLabelRect { [super drawTextInRect:UIEdgeInsetsInsetRect(uiLabelRect, UIEdgeInsetsMake(topInset,leftInset,bottomInset,rightInset))];}
EDIT #1:
From what I have seen, it seems you have to override the intrinsicContentSize of the UILabel when subclassing it.
So you should override intrinsicContentSize like:
- (CGSize) intrinsicContentSize { CGSize intrinsicSuperViewContentSize = [super intrinsicContentSize] ; intrinsicSuperViewContentSize.height += topInset + bottomInset ; intrinsicSuperViewContentSize.width += leftInset + rightInset ; return intrinsicSuperViewContentSize ;}
And add the following method to edit your insets, instead of editing them individually:
- (void) setContentEdgeInsets:(UIEdgeInsets)edgeInsets { topInset = edgeInsets.top; leftInset = edgeInsets.left; rightInset = edgeInsets.right; bottomInset = edgeInsets.bottom; [self invalidateIntrinsicContentSize] ;}
It will update the size of your UILabel to match the edge insets and cover the multiline necessity you referred to.
Edit #2
After searching a bit I have found this Gist with an IPInsetLabel. If none of those solutions work you could try it out.
Edit #3
There was a similar question (duplicate) about this matter.
For a full list of available solutions, see this answer: UILabel text margin
Swift 3
import UIKitclass PaddingLabel: UILabel { @IBInspectable var topInset: CGFloat = 5.0 @IBInspectable var bottomInset: CGFloat = 5.0 @IBInspectable var leftInset: CGFloat = 5.0 @IBInspectable var rightInset: CGFloat = 5.0 override func drawText(in rect: CGRect) { let insets = UIEdgeInsets(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset) super.drawText(in: UIEdgeInsetsInsetRect(rect, insets)) } override var intrinsicContentSize: CGSize { get { var contentSize = super.intrinsicContentSize contentSize.height += topInset + bottomInset contentSize.width += leftInset + rightInset return contentSize } }}