简体   繁体   English

向 UILabel 添加左/右水平填充

[英]Add left/right horizontal padding to UILabel

I need to create a UILabel with a background color, and I'd like to add some left/right leading/trailing horizontal padding.我需要创建一个带有背景颜色的UILabel ,并且我想添加一些左/右前导/尾随水平填充。

But every solution I've found seems like a nasty hack.但是我找到的每个解决方案似乎都是一个讨厌的黑客。

What is the 'standard' way to achieve this from iOS 5 forward?从 iOS 5 向前实现这一目标的“标准”方法是什么?

A screenshot to illustrate my scenario:一个截图来说明我的场景:

需要左填充

For a full list of available solutions, see this answer: UILabel text margin有关可用解决方案的完整列表,请参阅此答案: UILabel text margin


Try subclassing UILabel, like @Tommy Herbert suggests in the answer to [this question][1].尝试对 UILabel 进行子类化,就像@Tommy Herbert 在 [this question][1] 的答案中建议的那样。 Copied and pasted for your convenience:为方便起见复制粘贴:

I solved this by subclassing UILabel and overriding drawTextInRect: like this:我通过继承 UILabel 并覆盖 drawTextInRect: 解决了这个问题:

- (void)drawTextInRect:(CGRect)rect {
    UIEdgeInsets insets = {0, 5, 0, 5};
    [super drawTextInRect:UIEdgeInsetsInsetRect(rect, insets)];
}

The most important part is that you must override both intrinsicContentSize() and drawTextInRect() in order to account for AutoLayout:最重要的部分是您必须同时覆盖intrinsicContentSize()drawTextInRect()以考虑 AutoLayout:

var contentInset: UIEdgeInsets = .zero {
    didSet {
        setNeedsDisplay()
    }
}

override public var intrinsicContentSize: CGSize {
    let size = super.intrinsicContentSize
    return CGSize(width: size.width + contentInset.left + contentInset.right, height: size.height + contentInset.top + contentInset.bottom)
}

override public func drawText(in rect: CGRect) {
    super.drawText(in: UIEdgeInsetsInsetRect(rect, contentInset))
}

add a space character too the string.在字符串中添加一个空格字符。 that's poor man's padding :)那是穷人的填充物:)

OR

I would go with a custom background view but if you don't want that, the space is the only other easy options I see...我会使用自定义背景视图,但如果您不想要,空间是我看到的唯一其他简单选项......

OR write a custom label.或编写自定义标签。 render the text via coretext通过 coretext 渲染文本

#define PADDING 5

@interface MyLabel : UILabel

@end

@implementation MyLabel

- (void)drawTextInRect:(CGRect)rect {
    UIEdgeInsets insets = UIEdgeInsetsMake(0, PADDING, 0, PADDING);
    CGRect rect = UIEdgeInsetsInsetRect(rect, insets);
    return [super drawTextInRect:rect];
}

- (CGRect)textRectForBounds:(CGRect)bounds
     limitedToNumberOfLines:(NSInteger)numberOfLines
{
    CGSize size = CGSizeMake(999, 999);
    CGRect rect = [self.attributedText
                   boundingRectWithSize:size
                                options:NSStringDrawingUsesLineFragmentOrigin
                                context:nil];
    return CGRectInset(rect, -PADDING, 0);
}

@end
UIView* bg = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.frame.size.width, 70)];
bg.backgroundColor = [UIColor blackColor];
UILabel* yourLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, y, yourWidth, yourHeight)];
[bg addSubview:yourLabel];

[self addSubview:bg];

Sometimes it's convenient to use UNICODE partial spaces to achieve alignment while prototyping.有时在原型设计时使用 UNICODE 部分空格来实现对齐是很方便的。 This can be handy in prototyping, proof-of-concept, or just to defer implementation of graphics algorithms.这在原型设计、概念验证或只是推迟图形算法的实现中非常有用。

If you use UNICODE spaces for convenience, be aware that at least one of the UNICODE spaces has a size based on the font it is displayed from, specifically the actual space character itself (U+0020, ASCII 32)如果您为了方便而使用 UNICODE 空格,请注意至少一个 UNICODE 空格的大小取决于它所显示的字体,特别是实际的空格字符本身 (U+0020, ASCII 32)

If you're using the default iOS system font in a UILabel, the default System font characteristics could change in a subsequent iOS release and suddenly introduce an unwanted misalignment by changing your app's precise spacing.如果您在 UILabel 中使用默认的 iOS 系统字体,默认的系统字体特征可能会在后续的 iOS 版本中更改,并通过更改应用程序的精确间距突然引入不必要的错位。 This can and does happen, for example the "San Francisco" font replaced a previous iOS system font in an iOS release.这可能并且确实发生,例如“旧金山”字体替换了 iOS 版本中以前的 iOS 系统字体。

UNICODE easy to specify in Swift, for example:在 Swift 中很容易指定 UNICODE,例如:

let six_per_em_space = "\u{2006}"

Alternatively, cut/paste the space from an HTML page directly into the UILabel's text field in Interface Builder.或者,将 HTML 页面中的空间直接剪切/粘贴到界面生成器中 UILabel 的文本字段中。

Note: Attached pic is a screenshot, not HTML, so visit the linked page if you want to cut/paste the space.注意:附上的图片是截图,不是HTML,所以如果你想剪切/粘贴空间,请访问链接页面

UNICODE 空间

I had a couple of issues with the answers here, such as when you added in the padding, the width of the content was overflowing the box and that I wanted some corner radius.我在这里的答案有几个问题,例如当您添加填充时,内容的宽度溢出了框,并且我想要一些圆角半径。 I solved this using the following subclass of UILabel:我使用以下 UILabel 子类解决了这个问题:

#import "MyLabel.h"

#define PADDING 8.0
#define CORNER_RADIUS 4.0

@implementation MyLabel

- (void)drawRect:(CGRect)rect {
 self.layer.masksToBounds = YES;
 self.layer.cornerRadius = CORNER_RADIUS;
 UIEdgeInsets insets = {0, PADDING, 0, PADDING};
 return [super drawTextInRect:UIEdgeInsetsInsetRect(rect, insets)];
}
- (CGSize) intrinsicContentSize {
 CGSize intrinsicSuperViewContentSize = [super intrinsicContentSize] ;
 intrinsicSuperViewContentSize.width += PADDING * 2 ;
 return intrinsicSuperViewContentSize ;
}

@end

Hope that's helpful to someone!希望这对某人有帮助! Note that if you wanted padding on the top and bottom, you would need to change this lines:请注意,如果您想在顶部和底部填充,则需要更改以下行:

UIEdgeInsets insets = {0, PADDING, 0, PADDING};

To this:对此:

UIEdgeInsets insets = {PADDING, PADDING, PADDING, PADDING};

And add this line underneath the similar one for width:并在类似的宽度下面添加这一行:

intrinsicSuperViewContentSize.height += PADDING * 2 ;

Swift 5斯威夫特 5

Create below class file and set it to your label as custom class name through storyboard.创建下面的类文件,并通过故事板将其设置为您的标签作为自定义类名。 That's it.就是这样。

class PaddingLabel: UILabel {

    override func drawText(in rect: CGRect) {
        let insets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 0)//CGRect.inset(by:)
        super.drawText(in: rect.inset(by: insets))
    }
}

If you want to add padding to UILabel but not want to subclass it you can put your label in a UIView and give paddings with autolayout like:如果您想向UILabel添加填充但不想将其子类化,您可以将您的标签放在UIView并使用自动布局提供填充,例如:

使用 UIView 和自动布局填充

Result:结果:

结果

One thing I did to overcome this issue was to use a UIButton instead of a UILabel.我为克服这个问题所做的一件事是使用 UIButton 而不是 UILabel。 Then in the Attributes Inspector of the Interface Builder, I used the Edge for the Title as the padding.然后在界面生成器的属性检查器中,我使用标题的边缘作为填充。
If you do not attach the button to an action, when clicked it will not get selected but it will still show the highlight.如果您不将按钮附加到操作,则单击它时不会被选中,但仍会显示突出显示。

You can also do this programmatically with the following code:您还可以使用以下代码以编程方式执行此操作:

UIButton *mButton = [[UIButton alloc] init];
[mButton setTitleEdgeInsets:UIEdgeInsetsMake(top, left, bottom, right)];
[mButton setTitle:@"Title" forState:UIControlStateNormal];
[self.view addSubView:mButton];

This approach gives the same result but sometimes it did not work for some reason that I did not investigate since if possible I use the Interface Builder.这种方法给出了相同的结果,但有时由于我没有调查的某些原因它不起作用,因为如果可能我使用接口生成器。

This is still a workaround but it works quite nicely if the highlight doesn't bother you.这仍然是一种解决方法,但如果突出显示不打扰您,它会很好地工作。 Hope it is useful希望有用

Subclass UILabel and override drawTextInRect: like this:子类化 UILabel 并覆盖drawTextInRect:像这样:

- (void)drawTextInRect:(CGRect)rect 
{
    UIEdgeInsets insets = {0, 10, 0, 0};
    return [super drawTextInRect:UIEdgeInsetsInsetRect(rect, insets)];
}

Installation with CocoaPods使用 CocoaPods 安装

pod 'PaddingLabel', '1.2'

Change your UILabel class to PaddingLabel ###将您的 UILabel 类更改为 PaddingLabel ### 示例

Specify padding指定填充

在此处输入图片说明

If you need a more specific text alignment than what adding spaces to the left of the text provides, you can always add a second blank label of exactly how much of an indent you need.如果您需要比在文本左侧添加空格所提供的更具体的文本对齐方式,您始终可以添加第二个空白标签,说明您需要多少缩进。

I've got buttons with text aligned left with an indent of 10px and needed a label below to look in line.我有一些按钮,文本左对齐,缩进 10 像素,需要下面的标签来查看。 It gave the label with text and left alignment and put it at x=10 and then made a small second label of the same background color with a width = 10, and lined it up next to the real label.它给了带有文本和左对齐的标签,并将其放在 x=10 处,然后制作了一个相同背景颜色且宽度为 10 的小第二个标签,并将其排在真实标签旁边。

Minimal code and looks good.最少的代码,看起来不错。 Just makes AutoLayout a little more of a hassle to get everything working.只是让 AutoLayout 有点麻烦,让一切正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM