ios UILabel 文字边距

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3476646/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:32:39  来源:igfitidea点击:

UILabel text margin

ioscocoa-touchuikituilabel

提问by Ljdawson

I'm looking to set the left inset/margin of a UILabeland can't find a method to do so. The label has a background set so just changing its origin won't do the trick. It would be ideal to inset the text by 10pxor so on the left hand side.

我正在寻找设置 a 的左侧插图/边距,UILabel但找不到这样做的方法。该标签具有背景设置,因此仅更改其原点是行不通的。最好10px在左侧左右插入文本。

回答by Tommy Herbert

I solved this by subclassing UILabeland overriding drawTextInRect:like this:

我通过像这样子类化UILabel和覆盖来解决这个问题drawTextInRect:

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

Swift 3.1:

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

Swift 4.2.1:

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

As you might have gathered, this is an adaptation of tc.'s answer. It has two advantages over that one:

正如您可能已经收集到的那样,这是对tc.'s answer的改编。与它相比,它有两个优点:

  1. there's no need to trigger it by sending a sizeToFitmessage
  2. it leaves the label frame alone - handy if your label has a background and you don't want that to shrink
  1. 无需通过发送sizeToFit消息来触发它
  2. 它将标签框架单独保留 - 如果您的标签有背景并且您不希望它缩小,则很方便

回答by blyabtroi

For multiline text the left and the right margin can be set by using NSAttributedString.

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

回答by Brody Robertson

The best approach to add padding to a UILabel is to subclass UILabel and add an edgeInsets property. You then set the desired insets and the label will be drawn accordingly.

向 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

回答by Peter DeWeese

Subclassing is a little cumbersome for such a simple case. An alternative is to simply add the UILabel with no background set to a UIView with the background set. Set the label's x to 10 and make the outer view's size 20 pixels wider than the label.

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

回答by Imanou Petit

With Swift 3, you can have the desired effect by creating a subclass of UILabel. In this subclass, you will have to add a UIEdgeInsetsproperty with the required insets and override drawText(in:)method, intrinsicContentSizeproperty (for Auto layout code) and/or sizeThatFits(_:)method (for Springs & Struts code).

使用 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 heigth = superContentSize.height + padding.top + padding.bottom
        return CGSize(width: width, height: heigth)
    }

    // 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)
    }

}

The following example shows how to use PaddingLabelinstances in a UIViewController:

以下示例显示了如何PaddingLabel在 a 中使用实例UIViewController

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
    }

}

回答by Yariv Nissim

I ended up just adding some spaces to the text:

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

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

Ugly yet effective, and no subclassing required.

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

You can try "\t" as well. For a generic solution please refer to the accepted answer

你也可以试试 "\t"。有关通用解决方案,请参阅已接受的答案

回答by funct7

Swift version of Recycled Steel's answer + intrinsizeContentSize().

再生钢答案的 Swift 版本 + intrinsizeContentSize().

It supports a more traditional style of setting insets for other view objects with insets while being able to set insets in Interface Builder, i.e. insets are set like so programmatically:

它支持更传统的为其他带有插图的视图对象设置插图的风格,同时能够在 Interface Builder 中设置插图,即插图以编程方式设置:

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

Please let me know if there are any bugs.

请让我知道是否有任何错误。

Swift 4.2

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

Swift 3

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

Swift 2.2

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

回答by neverbendeasy

You can also solve this by initializing your UILabel with a custom frame.

您还可以通过使用自定义框架初始化 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];

Nod to CGRect Tricks.

CGRect 技巧致敬

回答by Arsonik

and an @IBDesignable that make it work with Interface Builder

和一个 @IBDesignable 使它与 Interface Builder 一起工作

Swift 4

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

Swift 2

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

回答by Millie Smith

For Xamarin users (using Unified API):

对于 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 ) );
    }
}

And for those using the original MonoTouch API:

对于那些使用原始 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));
    }
}