如何在iPhone应用中实现UIButton / UILabel的“padding”

73

我在iPhone应用程序中有各种视图需要填充,例如左对齐的自定义UIButton和具有背景颜色的UILabel。

这可能是一个非常愚蠢的问题,但我该如何应用“填充”来将文本移离左边缘?

我尝试使用bounds等方法都没有成功。

我知道我可以为我的UILabel创建一个具有背景颜色的包装视图,但这似乎太过繁琐。

非常感谢。


Marco Arment在推特上发布了一个非常简单的UILabel子类,它在标签绘制中添加了UIEdgeInsets样式的填充:它在gist.github上作为IPInsetLabel - cbowns
11个回答

118
我正在使用自动布局。对我有效的解决方案是设置UIButton的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)

2
未来的读者注意,contentEdgeInsets 似乎在 iOS 15 中已被弃用。现在当使用 UIButtonConfiguration 时,该属性将被忽略。与此相关的方法 .setDefaultContentInsets 正在搭配 Beta Software 通知一起发布。 - ufukty

22

好的,到目前为止我找到的最简单的解决方案是:

self.textAlignment = UITextAlignmentCenter; 
[self sizeToFit]; 
CGRect frame = self.frame;
frame.size.width += 20; //l + r padding 
self.frame = frame;

不完全是我想要的,但它可以工作。


我尝试调整这个解决方案以使其向左对齐,但失败了。这是一个非常古老的答案,我猜它在 iOS 6 上可能无法工作。希望有人能提供更新。 - Philip007
工作得很好,但从iOS 6.0开始,您必须使用NSTextAlignmentCenter,UITextAlignmentCenter已被弃用。 - chrisdowney

22
为了在UIButton文本中设置内边距,你需要使用UIButtoncontentEdgeInsets属性。
在Storyboard中,设置内容插图请按照以下步骤进行:
  1. 选择视图控制器,然后选择UIButton
  2. 进入“实用程序”面板(Command+Option+0),并选择“属性检查器”(Command+Option+4)
  3. 现在选择Edge中的Content,根据您的需求设置Inset(参见屏幕截图)

输入图片描述


5
现在它在尺寸检查器中。 - ilan
6
现在是在尺寸检查器下的按钮 -> 内容插图。 - Siddharth
3
从XCode 9开始,UIButton的Size Inspector中有一个Content Insets选项,如此图所示:https://dev59.com/z3A75IYBdhLWcg3w4tR7#49959281 - Bruno Bieri

9
要在UILabel上添加padding,最灵活的方法是子类化UILabel并添加一个edgeInsets属性。然后设置所需的插图,标签将相应地绘制。 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

6
在Xcode 9中,插图现在位于“Size Inspector”中,而不是“Attributes Inspector”中:

Xcode 9 Size Inspector - Button insets


3

以下是一个UILabel的子类,它拥有可自定义的padding,使用edgeInset属性:

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

(这是 Brody 的答案的简化版本,也适用于自动布局。)

2

CGRectInset 是您的好朋友。您可以设置负“插入”来创建填充:

[self sizeToFit];
CGRect rect = self.frame;
rect = CGRectInset( rect, -6.f, -5.f); // h inset, v inset
self.frame = rect;

0
创建一个自定义类,继承UIButton并覆盖以下内容:
- (CGRect)titleRectForContentRect:(CGRect)contentRect
{
    return UIEdgeInsetsInsetRect(contentRect, UIEdgeInsetsMake(topPadding, rightPadding, bottomPadding, leftPadding));
}

在UILabel的情况下,只需覆盖:
- (CGRect)textRectForBounds:(CGRect)bounds 
     limitedToNumberOfLines:(NSInteger)numberOfLines;

0

我正在尝试实现类似的功能,即“填充”UILabel。我一直在尝试实现Toby上面发布的解决方案,但似乎找不到需要放置在哪里。

我正在使用的UILabel是左对齐的 - 这是导致问题的原因吗?

我已经尝试在viewDidLoad中使用它,甚至在UILabel的子类中使用该方法:

- (CGRect)textRectForBounds:(CGRect)bounds
     limitedToNumberOfLines:(NSInteger)numberOfLines 

0
您可以在按钮按钮.titleLabel之间激活NSLayoutConstraint
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)
])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接