Reputation:
I've got various views in my iPhone application that require padding e.g a custom UIButton with text aligned left, and a UILabel with a background color.
This may be a really stupid question, but how can I apply 'padding' to move the text off the left hand edge?
I've tired using bounds etc without any success.
I know I could create a wrapper view for my UILabel
with a background color, but it seems like overkill.
Many thanks.
Upvotes: 74
Views: 65031
Reputation: 40048
I am using auto layout. Solution that worked for me was setting UIButton
's contentEdgeInsets
.
###ObjC
button.configuration.contentInsets = NSDirectionalEdgeInsetsMake(0.0f, 30.0f, 0.0f, 30.0f);
###Swift
button.configuration.contentInsets = NSDirectionalEdgeInsets(top: 0.0, left: 30.0, bottom: 0.0, right: 30.0)
Upvotes: 119
Reputation: 4005
You can activate NSLayoutConstraint
s between button
and button.titleLabel
let button = UIButton()
button.setTitle("Retake", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)
guard let label = button.titleLabel else { return }
NSLayoutConstraint.activate([
// setup constraints for button relative to view
label.leadingAnchor.constraint(equalTo: button.leadingAnchor, constant: 10),
label.centerXAnchor.constraint(equalTo: button.centerXAnchor)
])
Upvotes: 0
Reputation: 14408
To set padding in UIButton
text you need to use UIButton
's contentEdgeInsets
property.
In Storyboard, to set content inset do following steps:
UIButton
Upvotes: 22
Reputation: 2498
What about creating a custom class that extends UIButton and overriding this:
- (CGRect)titleRectForContentRect:(CGRect)contentRect
{
return UIEdgeInsetsInsetRect(contentRect, UIEdgeInsetsMake(topPadding, rightPadding, bottomPadding, leftPadding));
}
In the case of UILabel just override:
- (CGRect)textRectForBounds:(CGRect)bounds
limitedToNumberOfLines:(NSInteger)numberOfLines;
Upvotes: 0
Reputation: 1694
On Xcode 9, the insets are now located in the Size Inspector instead of the Attributes Inspector:
Upvotes: 6
Reputation: 2243
If you're just looking for a horizontal padding on one line, then this may be enough (it was for me):
NSString* padding = @" "; // 2 spaces
myLabel.text = [NSString stringWithFormat:@"%@%@%@", padding, name, padding];
Upvotes: -2
Reputation: 12041
Here's a sublass of UILabel that has customizable padding using an edgeInset property:
PaddedLabel.h
#import <UIKit/UIKit.h>
@interface PaddedLabel : UILabel
@property UIEdgeInsets edgeInsets;
@end
PaddedLabel.m
#import "PaddedLabel.h"
@implementation PaddedLabel
-(void)drawTextInRect:(CGRect)rect {
return [super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.edgeInsets)];
}
-(CGSize)intrinsicContentSize {
CGSize contentSize = [super intrinsicContentSize];
UIEdgeInsets insets = self.edgeInsets;
contentSize.height += insets.top + insets.bottom;
contentSize.width += insets.left + insets.right;
return contentSize;
}
@end
(This is a simplification of Brody's answer which also works with autolayout.)
Upvotes: 3
Reputation: 493
I'm trying to achieve a similar thing, that is 'pad' a UILabel
. I've been trying to implement the solution that Toby posted above, but can't seem to find where this needs to go.
The UILabel I'm working with is aligned left - is that what's causing the issue?
I've tried using this in viewDidLoad
, and even in a subclass of UILabel in the method:
- (CGRect)textRectForBounds:(CGRect)bounds
limitedToNumberOfLines:(NSInteger)numberOfLines
Upvotes: 0
Reputation: 5685
CGRectInset is your friend. You can set negative 'insets' to create padding:
[self sizeToFit];
CGRect rect = self.frame;
rect = CGRectInset( rect, -6.f, -5.f); // h inset, v inset
self.frame = rect;
Upvotes: 2
Reputation: 8604
To add padding to UILabel the most flexible approach 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;
}
-(id)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if(self){
self.edgeInsets = UIEdgeInsetsMake(0, 0, 0, 0);
}
return self;
}
- (void)drawTextInRect:(CGRect)rect {
return [super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.edgeInsets)];
}
@end
Upvotes: 9
Reputation:
Ok the simplest solution I've found so far is:
self.textAlignment = UITextAlignmentCenter;
[self sizeToFit];
CGRect frame = self.frame;
frame.size.width += 20; //l + r padding
self.frame = frame;
Not exactly what I wanted, but it works.
Upvotes: 22