UILabel text margin
I solved this by subclassing UILabel
and overriding drawTextInRect:
like this:
- (void)drawTextInRect:(CGRect)rect {
UIEdgeInsets insets = {0, 5, 0, 5};
[super drawTextInRect:UIEdgeInsetsInsetRect(rect, insets)];
}
Swift 3.1:
override func drawText(in rect: CGRect) {
let insets = UIEdgeInsets.init(top: 0, left: 5, bottom: 0, right: 5)
super.drawText(in: UIEdgeInsetsInsetRect(rect, insets))
}
Swift 4.2.1:
override func drawText(in rect: CGRect) {
let insets = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
super.drawText(in: rect.inset(by: insets))
}
As you might have gathered, this is an adaptation of tc.'s answer. It has two advantages over that one:
- there's no need to trigger it by sending a
sizeToFit
message - it leaves the label frame alone - handy if your label has a background and you don't want that to shrink
For multiline text the left and the right margin can be set by using NSAttributedString.
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
style.alignment = NSTextAlignmentJustified;
style.firstLineHeadIndent = 10.0f;
style.headIndent = 10.0f;
style.tailIndent = -10.0f;
NSAttributedString *attrText = [[NSAttributedString alloc] initWithString:title attributes:@{ NSParagraphStyleAttributeName : style}];
UILabel * label = [[UILabel alloc] initWithFrame:someFrame];
label.numberOfLines = 0;
label.attributedText = attrText;
Here is the above example adopted to Swift 5:
extension UILabel {
func setMargins(margin: CGFloat = 10) {
if let textString = self.text {
var paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.firstLineHeadIndent = margin
paragraphStyle.headIndent = margin
paragraphStyle.tailIndent = -margin
let attributedString = NSMutableAttributedString(string: textString)
attributedString.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: attributedString.length))
attributedText = attributedString
}
}
}
The best approach to add padding to a UILabel is to subclass UILabel and add an edgeInsets property. You then set the desired insets and the label will be drawn accordingly.
OSLabel.h
#import <UIKit/UIKit.h>
@interface OSLabel : UILabel
@property (nonatomic, assign) UIEdgeInsets edgeInsets;
@end
OSLabel.m
#import "OSLabel.h"
@implementation OSLabel
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
self.edgeInsets = UIEdgeInsetsMake(0, 0, 0, 0);
}
return self;
}
- (void)drawTextInRect:(CGRect)rect {
[super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.edgeInsets)];
}
- (CGSize)intrinsicContentSize
{
CGSize size = [super intrinsicContentSize];
size.width += self.edgeInsets.left + self.edgeInsets.right;
size.height += self.edgeInsets.top + self.edgeInsets.bottom;
return size;
}
@end