我有一个UILabel,我想在顶部和底部添加空格。在限制最小高度的情况下,我将其修改为:

为了做到这一点,我使用了:

override func drawTextInRect(rect: CGRect) {
    var insets: UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 10.0, bottom: 0.0, right: 10.0)
    super.drawTextInRect(UIEdgeInsetsInsetRect(rect, insets))
}

但我必须找到不同的方法,因为如果我写了超过两行,问题是一样的:


当前回答

一个实用的解决方案是添加与主标签高度和颜色相同的空白标签。将主标签的前导/尾距设置为零,对齐垂直中心,并设置所需的宽度。

其他回答

我的解决方案与人们回答的类似,但添加了sizeThatFits来帮助UIKit找出正确的大小。

class InsetLabel : UILabel {
    @objc var textInsets: UIEdgeInsets = .zero

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

    override func sizeThatFits(_ size: CGSize) -> CGSize {
        var s = super.sizeThatFits(CGSize(width: size.width - (textInsets.left + textInsets.right), height: size.height - (textInsets.top + textInsets.bottom)))
        s.height += textInsets.top + textInsets.bottom
        return s
    }
}

斯威夫特 4+

let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.firstLineHeadIndent = 10

// Swift 4.2++
label.attributedText = NSAttributedString(string: "Your text", attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle])

// Swift 4.1--
label.attributedText = NSAttributedString(string: "Your text", attributes: [NSAttributedStringKey.paragraphStyle: paragraphStyle])

Swift 3、iOS10解决方案:

open class UIInsetLabel: UILabel {

    open var insets : UIEdgeInsets = UIEdgeInsets() {
        didSet {
            super.invalidateIntrinsicContentSize()
        }
    }

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

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

简单的方法

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        self.view.addSubview(makeLabel("my title",x: 0, y: 100, w: 320, h: 30))
    }

    func makeLabel(title:String, x:CGFloat, y:CGFloat, w:CGFloat, h:CGFloat)->UILabel{
        var myLabel : UILabel = UILabel(frame: CGRectMake(x,y,w,h))
        myLabel.textAlignment = NSTextAlignment.Right

        // inser last char to right
        var titlePlus1char = "\(title)1"
        myLabel.text = titlePlus1char
        var titleSize:Int = count(titlePlus1char)-1

        myLabel.textColor = UIColor(red:1.0, green:1.0,blue:1.0,alpha:1.0)
        myLabel.backgroundColor = UIColor(red: 214/255, green: 167/255, blue: 0/255,alpha:1.0)


        // create myMutable String
        var myMutableString = NSMutableAttributedString()

        // create myMutable font
        myMutableString = NSMutableAttributedString(string: titlePlus1char, attributes: [NSFontAttributeName:UIFont(name: "HelveticaNeue", size: 20)!])

        // set margin size
        myMutableString.addAttribute(NSFontAttributeName, value: UIFont(name: "HelveticaNeue", size: 10)!, range: NSRange(location: titleSize,length: 1))

        // set last char to alpha 0
        myMutableString.addAttribute(NSForegroundColorAttributeName, value: UIColor(red:1.0, green:1.0,blue:1.0,alpha:0), range: NSRange(location: titleSize,length: 1))

        myLabel.attributedText = myMutableString

        return myLabel
    }


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

如果你想坚持使用UILabel,而不子类化它,Mundi已经给了你一个明确的解决方案。

如果你想避免用UIView来包装UILabel,你可以使用UITextView来支持UIEdgeInsets (padding)或者子类UILabel来支持UIEdgeInsets。

使用UITextView只需要提供insets (Objective-C):

textView.textContainerInset = UIEdgeInsetsMake(10, 0, 10, 0);

另外,如果你子类化UILabel,这种方法的一个例子是重写drawTextInRect方法 (objective - c)

- (void)drawTextInRect:(CGRect)uiLabelRect {
    UIEdgeInsets myLabelInsets = {10, 0, 10, 0};
    [super drawTextInRect:UIEdgeInsetsInsetRect(uiLabelRect, myLabelInsets)];
}

您还可以为您的新子类UILabel提供带有insets变量的TOP, LEFT, BOTTOM和RIGHT。

一个示例代码可以是:

In .h (Objective-C)

float topInset, leftInset,bottomInset, rightInset;

在。m (Objective-C)中

- (void)drawTextInRect:(CGRect)uiLabelRect {
    [super drawTextInRect:UIEdgeInsetsInsetRect(uiLabelRect, UIEdgeInsetsMake(topInset,leftInset,bottomInset,rightInset))];
}

从我所看到的,似乎你必须在子类化UILabel时重写它的intrinsicContentSize。

所以你应该像这样重写intrinsicContentSize:

- (CGSize) intrinsicContentSize {
    CGSize intrinsicSuperViewContentSize = [super intrinsicContentSize] ;
    intrinsicSuperViewContentSize.height += topInset + bottomInset ;
    intrinsicSuperViewContentSize.width += leftInset + rightInset ;
    return intrinsicSuperViewContentSize ;
}

并添加以下方法来编辑您的嵌入,而不是单独编辑它们:

- (void) setContentEdgeInsets:(UIEdgeInsets)edgeInsets {
    topInset = edgeInsets.top;
    leftInset = edgeInsets.left;
    rightInset = edgeInsets.right;
    bottomInset = edgeInsets.bottom;
    [self invalidateIntrinsicContentSize] ;
}

它将更新UILabel的大小,以匹配边缘插入并覆盖您提到的多行需求。

经过搜索,我找到了一个IPInsetLabel的Gist。如果这些方法都不起作用,你可以尝试一下。

关于这件事,还有一个类似的问题(重复)。 有关可用解决方案的完整列表,请参阅以下答案:UILabel文本边距