我有一个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))
}

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


当前回答

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

其他回答

简单填充(Swift 3.0, Alvin George回答):

  class NewLabel: UILabel {

        override func textRect(forBounds bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect {
                return self.bounds.insetBy(dx: CGFloat(15.0), dy: CGFloat(15.0))
        }

        override func draw(_ rect: CGRect) {
                super.drawText(in: self.bounds.insetBy(dx: CGFloat(5.0), dy: CGFloat(5.0)))
        }

  }

我在任何地方都没有看到这个答案。我的技巧是在标签上设置宽度限制,并在设置标签文本时调整宽度。

self.myLabel.text = myString;

UIFont * const font = [UIFont systemFontOfSize:17 weight:UIFontWeightRegular]; // Change to your own label font.

CGSize const size = CGSizeMake(INFINITY, 18); // 18 is height of label.

CGFloat const textWidth = [myString boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: font} context:nil].size.width;

self.myLabelWidthConstraint.constant = textWidth + 20; // 10 padding on each side. Also, set text alignment to centre.

类似于其他答案,但使用func类来动态地设置填充:

class UILabelExtendedView: UILabel
{
    var topInset: CGFloat = 4.0
    var bottomInset: CGFloat = 4.0
    var leftInset: CGFloat = 8.0
    var rightInset: CGFloat = 8.0

    override func drawText(in rect: CGRect)
    {
        let insets: UIEdgeInsets = UIEdgeInsets(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset)
        super.drawText(in: UIEdgeInsetsInsetRect(rect, insets))
    }

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

    func setPadding(top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat){
        self.topInset = top
        self.bottomInset = bottom
        self.leftInset = left
        self.rightInset = right
        let insets: UIEdgeInsets = UIEdgeInsets(top: top, left: left, bottom: bottom, right: right)
        super.drawText(in: UIEdgeInsetsInsetRect(self.frame, insets))
    }
}

如果你不想或需要在Storyboard中使用@IBInspectable / @IBDesignable UILabel(我认为那些渲染太慢了),那么使用UIEdgeInsets而不是4个不同的cgfloat会更干净。

Swift 4.2的代码示例:

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

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

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

详细阐述Mundi的回答。

例如,在UIView中嵌入一个标签,并通过自动布局强制填充。例子:

概述:

创建一个UIView(面板),并设置它的外观。 创建一个UILabel并将其添加到面板中。 添加约束以强制填充。 将面板添加到视图层次结构中,然后定位面板。

细节:

创建面板视图。 let panel = UIView() 面板。backgroundColor = .green panel.layer.cornerRadius = 12 创建标签,将其作为子视图添加到面板。 let label = UILabel() panel.addSubview(标签) 在标签的边缘和面板之间添加约束。这迫使面板与标签保持一定距离。也就是说,“填充”。

编辑:手工完成所有这些是超级乏味、冗长和容易出错的。我建议你从GitHub中选择一个自动布局包装器或自己写一个

label.panel.translatesAutoresizingMaskIntoConstraints = false
label.topAnchor.constraint(equalTo: panel.topAnchor,
    constant: vPadding).isActive = true
label.bottomAnchor.constraint(equalTo: panel.bottomAnchor,
    constant: -vPadding).isActive = true
label.leadingAnchor.constraint(equalTo: panel.leadingAnchor,
    constant: hPadding).isActive = true
label.trailingAnchor.constraint(equalTo: panel.trailingAnchor,
    constant: -hPadding).isActive = true

label.textAlignment = .center

将面板添加到视图层次结构中,然后添加定位约束。例如,拥抱tableViewCell的右侧,如示例图像中所示。

注意:您只需要添加位置约束,而不是尺寸约束:Auto Layout将基于标签的intrinsicContentSize和前面添加的约束来解决布局问题。

hostView.addSubview(panel)
panel.translatesAutoresizingMaskIntoConstraints = false
panel.trailingAnchor.constraint(equalTo: hostView.trailingAnchor,
    constant: -16).isActive = true
panel.centerYAnchor.constraint(equalTo: hostView.centerYAnchor).isActive = true