UILabel文本边距

我正在寻找设置UILabel的左插入/边距,但找不到这样做的方法。标签有一个背景集,所以仅仅改变它的原点是行不通的。最理想的情况是在左侧通过10px之类的方法插入文本。

309655 次浏览

我认为UILabel类没有设置边距的方法。为什么不把标签的位置设置在需要的位置?

见下面的代码:

UILabel *label = [[UILabel alloc] init];
label.text = @"This is label";
label.frame = CGRectMake(0,0,100,100);

如果来自接口构建器,则按以下方式定位Label:

yourLabel.frame = CGRectMake(0,0,100,100);

如果你不想使用一个额外的父视图来设置背景,你可以子类化UILabel并覆盖textRectForBounds:limitedToNumberOfLines:。我会添加一个textEdgeInsets属性或类似的,然后做

- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines
{
return [super textRectForBounds:UIEdgeInsetsInsetRect(bounds,textEdgeInsets) limitedToNumberOfLines:numberOfLines];
}

为了健壮性,你可能还想在setTextEdgeInsets:中调用[self setNeedsDisplay],但我通常不这么做。

我通过子类化UILabel并重写drawTextInRect:来解决这个问题,就像这样:

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

斯威夫特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))
}

斯威夫特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))
}

正如你可能已经收集到的,这是tc。的回答的改编。它有两个优点:

  1. 没有必要通过发送sizeToFit消息来触发它
  2. 它只保留标签框架——如果你的标签有背景,而你不想让它缩小,这很方便

对于这样一个简单的情况,子类化有点麻烦。另一种方法是将没有背景设置的UILabel添加到有背景设置的UIView中。将标签的x设置为10,并使外部视图的大小比标签宽20个像素。

也许你可以试试这段代码

CGRect frame = btn.titleLabel.frame;
int indent = 20;
int inset = 20;
[btn.titleLabel setFrame:CGRectMake(frame.origin.x+inset,frame.origin.y,frame.size.width+indent,frame.size.height)];

编辑:这个真的很老了。上面有更好的解决方案。

我最终只是在文本中添加了一些空格:

self.titleLabel.text = [NSString stringWithFormat:@"    %@", self.titleLabel.text];

丑陋但有效,不需要子类化。

你可以试试"\t"也对于一般的解决方案,请参考已接受的答案

为UILabel添加填充的最佳方法是子类化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;
}


- (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

将标签的textAlignment属性设置为NSTextAlignmentRight并增大其宽度。

你也可以用一个自定义框架初始化你的UILabel来解决这个问题。

    CGRect initialFrame = CGRectMake(0, 0, 100, 100);
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0, 10, 0, 0);
CGRect paddedFrame = UIEdgeInsetsInsetRect(initialFrame, contentInsets);


self.label = [[UILabel alloc] initWithFrame:paddedFrame];

指向CGRect中技巧

对于多行文本,可以使用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;

下面是上面用于斯威夫特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
}
}
}

对于Xamarin用户(使用统一API):

class UIMarginLabel : UILabel
{
public UIMarginLabel()
{
}


public UIMarginLabel( CGRect frame ) : base( frame )
{
}


public UIEdgeInsets Insets { get; set; }


public override void DrawText( CGRect rect )
{
base.DrawText( Insets.InsetRect( rect ) );
}
}

对于那些使用原始MonoTouch API的人:

public class UIMarginLabel : UILabel
{
public UIEdgeInsets Insets { get; set; }


public UIMarginLabel() : base()
{
Insets = new UIEdgeInsets(0, 0, 0, 0);
}
public UIMarginLabel(RectangleF frame) : base(frame)
{
Insets = new UIEdgeInsets(0, 0, 0, 0);
}


public override void DrawText(RectangleF frame)
{
base.DrawText(new RectangleF(
frame.X + Insets.Left,
frame.Y + Insets.Top,
frame.Width - Insets.Left - Insets.Right,
frame.Height - Insets.Top - Insets.Bottom));
}
}

如果你在iOS 6+中使用自动布局,你可以通过在UILabel的子类中调整intrinsicContentSize来做到这一点。

- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.textAlignment = NSTextAlignmentRight;
}
return self;
}


- (CGSize)intrinsicContentSize
{
CGSize size = [super intrinsicContentSize];
return CGSizeMake(size.width + 10.0, size.height);
}

为了消除单行标签的垂直填充,我做了:

// I have a category method setFrameHeight; you'll likely need to modify the frame.
[label setFrameHeight:font.pointSize];

或者,不带类别,使用:

CGRect frame = label.frame;
frame.size.height = font.pointSize;
label.frame = frame;

可以使用https://github.com/mattt/TTTAttributedLabel代替UILabel

BITAttributedLabel *label = [BITAttributedLabel new];
label.font = font;
label.text = @"hello";
label.textInsets = UIEdgeInsetsMake(10, 10, 10, 10);
[label sizeToFit];

在Swift中,它是这样解决的。

class Label: UILabel {
override func drawTextInRect(rect: CGRect) {
super.drawTextInRect(UIEdgeInsetsInsetRect(rect, UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10)))
}
}

这是我发现的最简单的方法。这对我来说很有魔力。

UIView *titleSection = [[UIView alloc] initWithFrame:CGRectMake(0, 0, screenWidth, 100)];
[titleSection addSubview:titleSection];


UILabel *label = [[UILabel alloc] initWithFrame:CGRectInset(titleSection.frame, PADDING, 0)];
[titleSection addSubview:label];

Xcode 6.1.1 Swift扩展解决方案。

文件名可以是"UILabel+AddInsetMargin.swift":

import UIKit


extension UILabel
{
public override func drawRect(rect: CGRect)
{
self.drawTextInRect(UIEdgeInsetsInsetRect(rect, UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)))
}
}

很多答案都缺少对sizeThatFits的重写。有了这个子类,你可以创建标签,设置填充,然后输入label。sizetofit(),瞧。

import UIKit


class UILabelEx : UILabel
{
var padding : UIEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)


override func drawTextInRect(rect: CGRect) {


super.drawTextInRect(UIEdgeInsetsInsetRect(rect, padding))
}


override func sizeThatFits(size: CGSize) -> CGSize
{


var adjSize = super.sizeThatFits(size)
adjSize.width += padding.left + padding.right
adjSize.height += padding.top + padding.bottom


return adjSize
}
}

要扩展Brody Robertson提供的答案,您可以添加IB可设计位。这意味着您可以在Storyboard中调整标签。

enter image description here

在你的子类UILabel做

#import <UIKit/UIKit.h>


IB_DESIGNABLE


@interface insetLabel : UILabel


@property (nonatomic, assign) IBInspectable CGFloat leftEdge;
@property (nonatomic, assign) IBInspectable CGFloat rightEdge;
@property (nonatomic, assign) IBInspectable CGFloat topEdge;
@property (nonatomic, assign) IBInspectable CGFloat bottomEdge;


@property (nonatomic, assign) UIEdgeInsets edgeInsets;


@end

然后做;

#import "insetLabel.h"


@implementation insetLabel


- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
self.edgeInsets = UIEdgeInsetsMake(self.topEdge, self.leftEdge, self.bottomEdge, self.rightEdge);
}
return self;
}


- (void)drawTextInRect:(CGRect)rect
{
self.edgeInsets = UIEdgeInsetsMake(self.topEdge, self.leftEdge, self.bottomEdge, self.rightEdge);


[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

编辑

你应该为edgeInsets添加一个setter方法。

在Swift 3中,你可以通过创建UILabel的子类来达到预期的效果。在这个子类中,你必须添加一个带有所需嵌套的UIEdgeInsets属性,并重写drawText(in:)方法、intrinsicContentSize属性(用于自动布局代码)和/或sizeThatFits(_:)方法(用于Springs &Struts代码)。

import UIKit


class PaddingLabel: UILabel {


let padding: UIEdgeInsets


// Create a new PaddingLabel instance programamtically with the desired insets
required init(padding: UIEdgeInsets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10)) {
self.padding = padding
super.init(frame: CGRect.zero)
}


// Create a new PaddingLabel instance programamtically with default insets
override init(frame: CGRect) {
padding = UIEdgeInsets.zero // set desired insets value according to your needs
super.init(frame: frame)
}


// Create a new PaddingLabel instance from Storyboard with default insets
required init?(coder aDecoder: NSCoder) {
padding = UIEdgeInsets.zero // set desired insets value according to your needs
super.init(coder: aDecoder)
}


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


// Override `intrinsicContentSize` property for Auto layout code
override var intrinsicContentSize: CGSize {
let superContentSize = super.intrinsicContentSize
let width = superContentSize.width + padding.left + padding.right
let height = superContentSize.height + padding.top + padding.bottom
return CGSize(width: width, height: height)
}


// Override `sizeThatFits(_:)` method for Springs & Struts code
override func sizeThatFits(_ size: CGSize) -> CGSize {
let superSizeThatFits = super.sizeThatFits(size)
let width = superSizeThatFits.width + padding.left + padding.right
let heigth = superSizeThatFits.height + padding.top + padding.bottom
return CGSize(width: width, height: heigth)
}


}

下面的例子展示了如何在UIViewController中使用PaddingLabel实例:

import UIKit


class ViewController: UIViewController {


@IBOutlet weak var storyboardAutoLayoutLabel: PaddingLabel!
let autoLayoutLabel = PaddingLabel(padding: UIEdgeInsets(top: 20, left: 40, bottom: 20, right: 40))
let springsAndStructsLabel = PaddingLabel(frame: CGRect.zero)
var textToDisplay = "Lorem ipsum dolor sit er elit lamet."


override func viewDidLoad() {
super.viewDidLoad()


// Set autoLayoutLabel
autoLayoutLabel.text = textToDisplay
autoLayoutLabel.backgroundColor = .red
autoLayoutLabel.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(autoLayoutLabel)
autoLayoutLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30).isActive = true
autoLayoutLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true


// Set springsAndStructsLabel
springsAndStructsLabel.text = textToDisplay
springsAndStructsLabel.backgroundColor = .green
view.addSubview(springsAndStructsLabel)
springsAndStructsLabel.frame.origin = CGPoint(x: 30, y: 90)
springsAndStructsLabel.sizeToFit()


// Set storyboardAutoLayoutLabel
storyboardAutoLayoutLabel.text = textToDisplay
storyboardAutoLayoutLabel.backgroundColor = .blue
}


// Link this IBAction to a UIButton or a UIBarButtonItem in Storyboard
@IBAction func updateLabelText(_ sender: Any) {
textToDisplay = textToDisplay == "Lorem ipsum dolor sit er elit lamet." ? "Lorem ipsum." : "Lorem ipsum dolor sit er elit lamet."


// autoLayoutLabel
autoLayoutLabel.text = textToDisplay


// springsAndStructsLabel
springsAndStructsLabel.text = textToDisplay
springsAndStructsLabel.sizeToFit()


// storyboardAutoLayoutLabel
storyboardAutoLayoutLabel.text = textToDisplay
}


}

和@IBDesignable,使其与接口生成器一起工作

斯威夫特4

//
//  PaddedLabel.swift
//  TrainCentric
//
//  Created by Arsonik
//  https://stackoverflow.com/a/33244365/337934
//


import UIKit


@IBDesignable
class PaddedLabel: UILabel {


@IBInspectable var inset:CGSize = CGSize(width: 0, height: 0)


var padding: UIEdgeInsets {
var hasText:Bool = false
if let t = self.text?.count, t > 0 {
hasText = true
}
else if let t = attributedText?.length, t > 0 {
hasText = true
}


return hasText ? UIEdgeInsets(top: inset.height, left: inset.width, bottom: inset.height, right: inset.width) : UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}


override func drawText(in rect: CGRect) {
super.drawText(in: rect.inset(by: padding))
}


override var intrinsicContentSize: CGSize {
let superContentSize = super.intrinsicContentSize
let p = padding
let width = superContentSize.width + p.left + p.right
let heigth = superContentSize.height + p.top + p.bottom
return CGSize(width: width, height: heigth)
}


override func sizeThatFits(_ size: CGSize) -> CGSize {
let superSizeThatFits = super.sizeThatFits(size)
let p = padding
let width = superSizeThatFits.width + p.left + p.right
let heigth = superSizeThatFits.height + p.top + p.bottom
return CGSize(width: width, height: heigth)
}
}

斯威夫特2

@IBDesignable
class PaddedLabel: UILabel {


@IBInspectable var inset:CGSize = CGSize(width: 0, height: 0)


var padding: UIEdgeInsets {
var hasText:Bool = false
if let t = text?.length where t > 0 {
hasText = true
}
else if let t = attributedText?.length where t > 0 {
hasText = true
}


return hasText ? UIEdgeInsets(top: inset.height, left: inset.width, bottom: inset.height, right: inset.width) : UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}


override func drawTextInRect(rect: CGRect) {
super.drawTextInRect(UIEdgeInsetsInsetRect(rect, padding))
}


override func intrinsicContentSize() -> CGSize {
let superContentSize = super.intrinsicContentSize()
let p = padding
let width = superContentSize.width + p.left + p.right
let heigth = superContentSize.height + p.top + p.bottom
return CGSize(width: width, height: heigth)
}


override func sizeThatFits(size: CGSize) -> CGSize {
let superSizeThatFits = super.sizeThatFits(size)
let p = padding
let width = superSizeThatFits.width + p.left + p.right
let heigth = superSizeThatFits.height + p.top + p.bottom
return CGSize(width: width, height: heigth)
}
}

也许过会儿再去派对,但下面的就行了。只是UILabel的子类。

#import "UITagLabel.h"


#define padding UIEdgeInsetsMake(5, 10, 5, 10)


@implementation UITagLabel


- (void)drawTextInRect:(CGRect)rect {
[super drawTextInRect:UIEdgeInsetsInsetRect(rect, padding)];
}


- (CGSize) intrinsicContentSize {
CGSize superContentSize = [super intrinsicContentSize];
CGFloat width = superContentSize.width + padding.left + padding.right;
CGFloat height = superContentSize.height + padding.top + padding.bottom;
return CGSizeMake(width, height);
}


- (CGSize) sizeThatFits:(CGSize)size {
CGSize superSizeThatFits = [super sizeThatFits:size];
CGFloat width = superSizeThatFits.width + padding.left + padding.right;
CGFloat height = superSizeThatFits.height + padding.top + padding.bottom;
return CGSizeMake(width, height);
}


@end

这里有一个快速的解决方案。只需在文件底部添加这个自定义类(或为其创建一个新文件),并在创建标签时使用MyLabel而不是UILabel。

class MyLabel: UILabel{
override func drawTextInRect(rect: CGRect) {
super.drawTextInRect(UIEdgeInsetsInsetRect(rect, UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 0)))
}
}

没有子类和所有的爵士。我动态地做了这个:

[cell.textLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[cell.textLabel constraintTrailingEqualTo:cell.contentView constant:-100];

约束部分只是一个简单的代码糖纸(我们有相同的方法从上/下/左/右添加填充)..如果我在这里得到足够的爱,我将开放整个包装:

- (id)constraintTrailingEqualTo:(UIView *)toView constant:(CGFloat)constant
{
NSLayoutConstraint *cn = [NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:toView
attribute:NSLayoutAttributeTrailing
multiplier:1 constant:constant];


[toView addConstraint:cn];
return self;
}

(注意,我是在

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath;

你可能需要根据上下文调用[self setNeedsLayout];

再生钢铁的快速版本的答案+ intrinsizeContentSize()

它支持一个更传统的设置insets为其他视图对象的insets,同时能够设置insets在接口生成器,即insets设置像这样编程:

label.insets = UIEdgeInsetsMake(0, 0, 5, 0)

如果有任何错误,请告诉我。

斯威夫特5

@IBInspectable var topInset: CGFloat = 0.0
@IBInspectable var leftInset: CGFloat = 0.0
@IBInspectable var bottomInset: CGFloat = 0.0
@IBInspectable var rightInset: CGFloat = 0.0


var insets: UIEdgeInsets {
get {
return UIEdgeInsets(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset)
}
set {
topInset = newValue.top
leftInset = newValue.left
bottomInset = newValue.bottom
rightInset = newValue.right
}
}


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


override func sizeThatFits(_ size: CGSize) -> CGSize {
var adjSize = super.sizeThatFits(size)
adjSize.width += leftInset + rightInset
adjSize.height += topInset + bottomInset
    

return adjSize
}


override var intrinsicContentSize: CGSize {
var contentSize = super.intrinsicContentSize
contentSize.width += leftInset + rightInset
contentSize.height += topInset + bottomInset
    

return contentSize
}

斯威夫特4.2

@IBDesignable class InsetLabel: UILabel {
@IBInspectable var topInset: CGFloat = 0.0
@IBInspectable var leftInset: CGFloat = 0.0
@IBInspectable var bottomInset: CGFloat = 0.0
@IBInspectable var rightInset: CGFloat = 0.0
    

var insets: UIEdgeInsets {
get {
return UIEdgeInsetsMake(topInset, leftInset, bottomInset, rightInset)
}
set {
topInset = newValue.top
leftInset = newValue.left
bottomInset = newValue.bottom
rightInset = newValue.right
}
}
    

override func drawText(in rect: CGRect) {
super.drawText(in: rect.inset(by: insets))
}
    

override func sizeThatFits(_ size: CGSize) -> CGSize {
var adjSize = super.sizeThatFits(size)
adjSize.width += leftInset + rightInset
adjSize.height += topInset + bottomInset
        

return adjSize
}
    

override var intrinsicContentSize: CGSize {
var contentSize = super.intrinsicContentSize
contentSize.width += leftInset + rightInset
contentSize.height += topInset + bottomInset
        

return contentSize
}
}

斯威夫特3

@IBDesignable class InsetLabel: UILabel {
@IBInspectable var topInset: CGFloat = 0.0
@IBInspectable var leftInset: CGFloat = 0.0
@IBInspectable var bottomInset: CGFloat = 0.0
@IBInspectable var rightInset: CGFloat = 0.0
    

var insets: UIEdgeInsets {
get {
return UIEdgeInsetsMake(topInset, leftInset, bottomInset, rightInset)
}
set {
topInset = newValue.top
leftInset = newValue.left
bottomInset = newValue.bottom
rightInset = newValue.right
}
}
    

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

override func sizeThatFits(_ size: CGSize) -> CGSize {
var adjSize = super.sizeThatFits(size)
adjSize.width += leftInset + rightInset
adjSize.height += topInset + bottomInset
        

return adjSize
}
    

override var intrinsicContentSize: CGSize {
var contentSize = super.intrinsicContentSize
contentSize.width += leftInset + rightInset
contentSize.height += topInset + bottomInset
        

return contentSize
}
}

斯威夫特2.2

@IBDesignable class InsetLabel: UILabel {
@IBInspectable var topInset: CGFloat = 0.0
@IBInspectable var leftInset: CGFloat = 0.0
@IBInspectable var bottomInset: CGFloat = 0.0
@IBInspectable var rightInset: CGFloat = 0.0
    

var insets: UIEdgeInsets {
get {
return UIEdgeInsetsMake(topInset, leftInset, bottomInset, rightInset)
}
set {
topInset = newValue.top
leftInset = newValue.left
bottomInset = newValue.bottom
rightInset = newValue.right
}
}
        

override func drawTextInRect(rect: CGRect) {
super.drawTextInRect(UIEdgeInsetsInsetRect(rect, insets))
}
        

override func sizeThatFits(size: CGSize) -> CGSize {
var adjSize = super.sizeThatFits(size)
adjSize.width += leftInset + rightInset
adjSize.height += topInset + bottomInset
        

return adjSize
}
    

override func intrinsicContentSize() -> CGSize {
var contentSize = super.intrinsicContentSize()
contentSize.width += leftInset + rightInset
contentSize.height += topInset + bottomInset
        

return contentSize
}
}

blyabtroi的asnwer在Swift中转换(不需要子类化)

let style: NSMutableParagraphStyle = NSParagraphStyle.defaultParagraphStyle().mutableCopy() as! NSMutableParagraphStyle
style.alignment = .Justified
style.firstLineHeadIndent = 10.0
style.headIndent = 10.0
style.tailIndent = -10.0
let attrText: NSAttributedString = NSAttributedString(string: title, attributes: [NSParagraphStyleAttributeName:style])
let label: UILabel = UILabel(frame: someFrame)
label.numberOfLines = 0
label.attributedText = attrText

Swift 3 &自动布局兼容版本:

class InsetLabel: UILabel {


var insets = UIEdgeInsets()


convenience init(insets: UIEdgeInsets) {
self.init(frame: CGRect.zero)
self.insets = insets
}


convenience init(dx: CGFloat, dy: CGFloat) {
let insets = UIEdgeInsets(top: dy, left: dx, bottom: dy, right: dx)
self.init(insets: insets)
}


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


override var intrinsicContentSize: CGSize  {
var size = super.intrinsicContentSize
size.width += insets.left + insets.right
size.height += insets.top + insets.bottom
return size
}
}

只要在左边如果是单线的话中添加空格,就会有多于1行的填充为0。

[self.myLabel setText:[NSString stringWithFormat:@"   %@", self.myShortString]];

不要编码,Xcode !

与其使用UILabel来解决这个问题,我建议你看看UIButton。它提供了开箱即用的能力,在大小检查器中设置内容Insets(上,左,下,右)。设置所需的边距,在Xcode中< em >禁用< / em >按钮后,完成。

#import "E_LabelWithPadding.h"
#define padding UIEdgeInsetsMake(2, 0, 2, 0)
#define padding1 UIEdgeInsetsMake(0, 0, 0, 0)
@implementation E_LabelWithPadding
- (void)drawTextInRect:(CGRect)rect {
if (![self.text isEqualToString:@""]) {
[super drawTextInRect:UIEdgeInsetsInsetRect(rect, padding)];
}else {
[super drawTextInRect:UIEdgeInsetsInsetRect(rect, padding1)];
}

- (CGSize) intrinsicContentSize {
if (![self.text isEqualToString:@""]) {
CGSize superContentSize = [super intrinsicContentSize];
CGFloat width = superContentSize.width + padding.left + padding.right;
CGFloat height = superContentSize.height + padding.top + padding.bottom;
return CGSizeMake(width, height);
}else {
CGSize superContentSize = [super intrinsicContentSize];
CGFloat width = superContentSize.width + padding1.left + padding1.right;
CGFloat height = superContentSize.height + padding1.top + padding1.bottom;
return CGSizeMake(width, height);
}

- (CGSize) sizeThatFits:(CGSize)size {
if (![self.text isEqualToString:@""]) {
CGSize superSizeThatFits = [super sizeThatFits:size];
CGFloat width = superSizeThatFits.width + padding.left + padding.right;
CGFloat height = superSizeThatFits.height + padding.top + padding.bottom;
return CGSizeMake(width, height);
}else {
CGSize superSizeThatFits = [super sizeThatFits:size];
CGFloat width = superSizeThatFits.width + padding1.left + padding1.right;
CGFloat height = superSizeThatFits.height + padding1.top + padding1.bottom;
return CGSizeMake(width, height);
}

@end

很多答案都很复杂。在某些情况下,这是必要的。然而,如果你正在阅读这篇文章,你的标签没有左右边距,你只是想要一点填充,这里是整个解决方案:

第一步:在结尾添加空格(按几次空格键)

步骤2:设置标签的文本对齐方式为居中

完成

这适用于多行标签:

class PaddedLabel: UILabel {
var verticalPadding: CGFloat = 0
var horizontalPadding: CGFloat = 0


override func drawText(in rect: CGRect) {
let insets = UIEdgeInsets(top: verticalPadding, left: horizontalPadding, bottom: verticalPadding, right: horizontalPadding)
super.drawText(in: UIEdgeInsetsInsetRect(rect, insets))
}


override var intrinsicContentSize: CGSize {
get {
let textWidth = super.intrinsicContentSize.width - horizontalPadding * 2
let textHeight = sizeThatFits(CGSize(width: textWidth, height: .greatestFiniteMagnitude)).height
let width = textWidth + horizontalPadding * 2
let height = textHeight + verticalPadding * 2
return CGSize(width: frame.width, height: height)
}
}
}

如果以编程方式创建标签,则可以使用sizeThatFits方法计算填充。如果使用多行,文本将以最大宽度值换行。

let text = UILabel()
let padding = 10
text.layer.cornerRadius = 5
text.layer.masksToBounds = true
text.text = "Hello"
text.font = UIFont(name: text.font.fontName, size: 18)
text.textAlignment = NSTextAlignment.center
text.numberOfLines = 1


let maxSize = CGSize(width: 100, height: 100)
var size = text.sizeThatFits(maxSize)
size.width = size.width + padding * 2
size.height = size.height + padding * 2
text.frame = CGRect(origin: CGPoint(x: 0, y: 0), size: size)

我没有在上面的答案中找到使用UIButton的建议。我会试着证明这是一个好的选择。

button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8)

在我的情况下,使用UIButton是最好的解决方案,因为:

  • 我有一个简单的单行文本
  • 我不想使用UIView作为UILabel的容器(即,我想简化单元格中自动布局的数学计算)
  • 我不想使用NSParagraphStyle(因为tailIndent与自动布局不正确- UILabel的宽度小于预期)
  • 我不想使用UITextView(因为可能的副作用)
  • 我不想子类UILabel(更少的代码更少的bug)

这就是为什么使用UIButton 在我的情况下中的contentEdgeInsets成为添加文本边距的最简单方法。

希望这能帮助到一些人。

Swift 4版blyabtroi解决方案

let leadingMargin: CGFloat = 10
let trailingMargin: CGFloat = 10


let style = NSMutableParagraphStyle()
style.alignment = .justified
style.firstLineHeadIndent = leadingMargin
style.headIndent = leadingMargin
style.tailIndent = trailingMargin


label.attributedText = NSAttributedString(string: "Label with margins",
attributes: [NSAttributedStringKey.paragraphStyle: style])

我已经用xcode构建器解决了它(但肯定这可以通过swift使用约束来实现):

只需要创建一个相关大小的UIView 并添加一个UILabel类型的子视图到

好了,你有填充了:)

xcode builder solution

这是我找到的最简单的解决方法:

斯威夫特4

class CustomLabel: UILabel{
override func drawText(in rect: CGRect) {
super.drawText(in: rect.inset(by: UIEdgeInsets.init(top: 10, left: 10, bottom: 10, right: 10)))
}
}

确保将标签设置为CustomLabel在代码和故事板中。

你需要计算UILabel大小,当你放置嵌入。它可以有不同的行数,因为文本对齐,换行模式。

override func drawText(in rect: CGRect) {


let size = self.sizeThatFits(UIEdgeInsetsInsetRect(rect, insets).size);
super.drawText(in: CGRect.init(origin: CGPoint.init(x: insets.left, y: insets.top), size: size));
}


override var intrinsicContentSize: CGSize {


var size = super.intrinsicContentSize;


if text == nil || text?.count == 0 {
return size;
}


size = self.sizeThatFits(UIEdgeInsetsInsetRect(CGRect.init(origin: CGPoint.zero, size: size), insets).size);
size.width  += self.insets.left + self.insets.right;
size.height += self.insets.top + self.insets.bottom;


return size;
}

try iEun/InsetLabel