如何在 iPhone 应用程序中实现 UIButton/UILabel“填充”

在我的 iPhone 应用程序中有很多需要填充的视图,例如一个自定义的左对齐文本的 UIButton 和一个背景颜色的 UILabel。

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

我已经厌倦了使用界限等没有任何成功。

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

非常感谢。

62276 次浏览

目前为止,我找到的最简单的解决办法是:

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

虽然不是我想要的,但是很有效。

我试图达到一个类似的事情,这是’垫’一个 UILabel。我一直在尝试实现托比上面提出的解决方案,但似乎找不到需要解决的问题。 和我一起工作的 UILabel 是左对齐的——这是导致问题的原因吗?

我试过在 viewDidLoad中使用它,甚至在方法中的 UILabel 子类中也是如此:

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

要向 UILabel 添加填充,最灵活的方法是子类化 UILabel 并添加 edgeInsets 属性。然后设置所需的 insets,并相应地绘制标签。

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

CGRectInset 是你的朋友。你可以设置负的“ insets”来创建空白:

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

下面是 UILabel 的一个子集,它使用 edgeInset 属性具有可定制的填充:

PaddedLabel

#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

(这是布罗迪的回答的简化,也可以用于自动布局。)

如果你只是想在一条线上找到一个水平的填充物,那么这可能就足够了(对我来说) :

NSString* padding = @"  "; // 2 spaces
myLabel.text = [NSString stringWithFormat:@"%@%@%@", padding, name, padding];

我正在使用 自动布局。解决方案,为我工作是设置 UIButtoncontentEdgeInsets

目的

button.contentEdgeInsets = UIEdgeInsetsMake(0.0f, 30.0f, 0.0f, 30.0f);

斯威夫特

button.contentEdgeInsets = UIEdgeInsets(top: 0.0, left: 30.0, bottom: 0.0, right: 30.0)

要在 UIButton文本中设置填充,需要使用 UIButtoncontentEdgeInsets属性。

在 Storyboard 中,要设置内容插入,请执行以下步骤:

  1. 选择视图控制器,然后选择 UIButton
  2. 进入工具面板(命令 + 选项 + 0)并选择属性检查器(命令 + 选项 + 4)
  3. 现在选择 Edge中的 满足并按照您的 要求(见截图)

enter image description here

Xcode 9上,插入现在位于 尺寸检查员而不是属性检查器:

Xcode 9 Size Inspector - Button insets

如何创建一个扩展 UIButton 的自定义类并覆盖以下内容:

- (CGRect)titleRectForContentRect:(CGRect)contentRect
{
return UIEdgeInsetsInsetRect(contentRect, UIEdgeInsetsMake(topPadding, rightPadding, bottomPadding, leftPadding));
}

在 UILabel 的情况下,只需覆盖:

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

你可以激活 buttonbutton.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)
])