添加空格/填充到UILabel

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

但是我要find一个不同的方法,因为如果我写两行以上的话,问题是一样的:

在这里输入图像描述

如果你想坚持使用UILabel,而不需要inheritance它,蒙迪给了你一个明确的解决scheme。

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

使用UITextView只需要提供插入(OBJ-C):

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

另外,如果你inheritanceUILabel ,这个方法的一个例子就是覆盖drawTextInRect方法
(OBJ-C)

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

您还可以为TOP,LEFT,BOTTOM和RIGHT提供新的子类UILabel。

示例代码可以是:

在.h(OBJ-C)

 float topInset, leftInset,bottomInset, rightInset; 

在.m(OBJ-C)

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

编辑#1:

从我所看到的,似乎你必须覆盖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的大小来匹配边缘插槽,并覆盖你所提到的多行的必要性。

编辑#2

search了一下之后,我发现了这个Gist与IPInsetLabel。 如果这些解决scheme都不起作用,您可以尝试一下。

编辑#3

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

你可以从IB正确地做到这一点:

  1. 将文本更改为归因

归因文本

  1. 用“…”去下拉列表

在这里输入图像描述

  1. 你会看到一些填充属性的行,段落和文本更改缩进第一行或任何你想要的

在这里输入图像描述

  1. 检查结果

在这里输入图像描述

Swift 3

 import UIKit class PaddingLabel: UILabel { @IBInspectable var topInset: CGFloat = 5.0 @IBInspectable var bottomInset: CGFloat = 5.0 @IBInspectable var leftInset: CGFloat = 5.0 @IBInspectable var rightInset: CGFloat = 5.0 override func drawText(in rect: CGRect) { let insets = UIEdgeInsets(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset) super.drawText(in: UIEdgeInsetsInsetRect(rect, insets)) } override var intrinsicContentSize: CGSize { get { var contentSize = super.intrinsicContentSize contentSize.height += topInset + bottomInset contentSize.width += leftInset + rightInset return contentSize } } } 

我已经试过了,希望它对你有用!

 @IBDesignable class PaddingLabel: UILabel { @IBInspectable var topInset: CGFloat = 5.0 @IBInspectable var bottomInset: CGFloat = 5.0 @IBInspectable var leftInset: CGFloat = 7.0 @IBInspectable var rightInset: CGFloat = 7.0 override func drawTextInRect(rect: CGRect) { let insets = UIEdgeInsets(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset) super.drawTextInRect(UIEdgeInsetsInsetRect(rect, insets)) } override func intrinsicContentSize() -> CGSize { var intrinsicSuperViewContentSize = super.intrinsicContentSize() intrinsicSuperViewContentSize.height += topInset + bottomInset intrinsicSuperViewContentSize.width += leftInset + rightInset return intrinsicSuperViewContentSize } } 

只需使用UIView作为超级视图,并使用自动布局为标签定义固定边距。

SWIFT 3

易于使用的解决scheme,适用于项目中的所有UILabel子项目。

例:

 let label = UILabel() label.<Do something> label.padding = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 0) 

UILabel扩展

 import UIKit extension UILabel { private struct AssociatedKeys { static var padding = UIEdgeInsets() } public var padding: UIEdgeInsets? { get { return objc_getAssociatedObject(self, &AssociatedKeys.padding) as? UIEdgeInsets } set { if let newValue = newValue { objc_setAssociatedObject(self, &AssociatedKeys.padding, newValue as UIEdgeInsets!, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } } override open func draw(_ rect: CGRect) { if let insets = padding { self.drawText(in: UIEdgeInsetsInsetRect(rect, insets)) } else { self.drawText(in: rect) } } override open var intrinsicContentSize: CGSize { guard let text = self.text else { return super.intrinsicContentSize } var contentSize = super.intrinsicContentSize var textWidth: CGFloat = frame.size.width var insetsHeight: CGFloat = 0.0 if let insets = padding { textWidth -= insets.left + insets.right insetsHeight += insets.top + insets.bottom } let newSize = text.boundingRect(with: CGSize(width: textWidth, height: CGFloat.greatestFiniteMagnitude), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font: self.font], context: nil) contentSize.height = ceil(newSize.size.height) + insetsHeight return contentSize } } 

Swift 3代码及其实现示例

 class UIMarginLabel: UILabel { var topInset: CGFloat = 0 var rightInset: CGFloat = 0 var bottomInset: CGFloat = 0 var leftInset: CGFloat = 0 override func drawText(in rect: CGRect) { let insets: UIEdgeInsets = UIEdgeInsets(top: self.topInset, left: self.leftInset, bottom: self.bottomInset, right: self.rightInset) self.setNeedsLayout() return super.drawText(in: UIEdgeInsetsInsetRect(rect, insets)) } } class LabelVC: UIViewController { //Outlets @IBOutlet weak var labelWithMargin: UIMarginLabel! override func viewDidLoad() { super.viewDidLoad() //Label settings. labelWithMargin.leftInset = 10 view.layoutIfNeeded() } } 

不要忘记在故事板标签对象中添加类名称UIMarginLabel。 快乐编码!

子类UILabel。 (File-New-File-CocoaTouchClass -UMLabel的子类)。

 // sampleLabel.swift import UIKit class sampleLabel: UILabel { let topInset = CGFloat(5.0), bottomInset = CGFloat(5.0), leftInset = CGFloat(8.0), rightInset = CGFloat(8.0) override func drawTextInRect(rect: CGRect) { let insets: UIEdgeInsets = UIEdgeInsets(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset) super.drawTextInRect(UIEdgeInsetsInsetRect(rect, insets)) } override func intrinsicContentSize() -> CGSize { var intrinsicSuperViewContentSize = super.intrinsicContentSize() intrinsicSuperViewContentSize.height += topInset + bottomInset intrinsicSuperViewContentSize.width += leftInset + rightInset return intrinsicSuperViewContentSize } } 

在ViewController上:

 override func viewDidLoad() { super.viewDidLoad() let labelName = sampleLabel(frame: CGRectMake(0, 100, 300, 25)) labelName.text = "Sample Label" labelName.backgroundColor = UIColor.grayColor() labelName.textColor = UIColor.redColor() labelName.shadowColor = UIColor.blackColor() labelName.font = UIFont(name: "HelveticaNeue", size: CGFloat(22)) self.view.addSubview(labelName) } 

或者将Storyboard上的自定义UILabel类作为Label的类关联。

Swift 3,iOS10解决scheme:

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

只需使用已经内置的UIButton。closures所有额外的buttonfunction,并且您有一个可以设置边缘的标签。

 let button = UIButton() button.contentEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5) button.setTitle("title", for: .normal) button.tintColor = .white // this will be the textColor button.isUserInteractionEnabled = false 

我在接受的答案中编了一点。 leftInsetrightInset增加时会出现问题,部分文字会消失,b / c标签的宽度会变窄但高度不会增加如图:

填充内部大小错误的标签

要解决这个问题,你需要重新计算文本的高度如下:

 @IBDesignable class PaddingLabel: UILabel { @IBInspectable var topInset: CGFloat = 20.0 @IBInspectable var bottomInset: CGFloat = 20.0 @IBInspectable var leftInset: CGFloat = 20.0 @IBInspectable var rightInset: CGFloat = 20.0 override func drawTextInRect(rect: CGRect) { let insets = UIEdgeInsets(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset) super.drawTextInRect(UIEdgeInsetsInsetRect(rect, insets)) } override func intrinsicContentSize() -> CGSize { var intrinsicSuperViewContentSize = super.intrinsicContentSize() let textWidth = frame.size.width - (self.leftInset + self.rightInset) let newSize = self.text!.boundingRectWithSize(CGSizeMake(textWidth, CGFloat.max), options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: self.font], context: nil) intrinsicSuperViewContentSize.height = ceil(newSize.size.height) + self.topInset + self.bottomInset return intrinsicSuperViewContentSize } } 

结果是:

填充正确的内容大小的标签

我希望帮助一些和我一样的人。

易填充(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))) } } 

简单的方法

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

在Swift 3

最好和简单的方法

 class UILabelPadded: UILabel { override func drawText(in rect: CGRect) { let insets = UIEdgeInsets.init(top: 0, left: 5, bottom: 0, right: 5) super.drawText(in: UIEdgeInsetsInsetRect(rect, insets)) } } 

没有故事板:

 class PaddingLabel: UILabel { var topInset: CGFloat var bottomInset: CGFloat var leftInset: CGFloat var rightInset: CGFloat required init(withInsets top: CGFloat, _ bottom: CGFloat,_ left: CGFloat,_ right: CGFloat) { self.topInset = top self.bottomInset = bottom self.leftInset = left self.rightInset = right super.init(frame: CGRect.zero) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func drawText(in rect: CGRect) { let insets = UIEdgeInsets(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset) super.drawText(in: UIEdgeInsetsInsetRect(rect, insets)) } override var intrinsicContentSize: CGSize { get { var contentSize = super.intrinsicContentSize contentSize.height += topInset + bottomInset contentSize.width += leftInset + rightInset return contentSize } } } 

用法:

 let label = PaddingLabel(8, 8, 16, 16) label.font = .boldSystemFont(ofSize: 16) label.text = "Hello World" label.backgroundColor = .black label.textColor = .white label.textAlignment = .center label.layer.cornerRadius = 8 label.clipsToBounds = true label.sizeToFit() view.addSubview(label) 

结果:

易填充:

 import UIKit class NewLabel: UILabel { override func textRectForBounds(bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect { return CGRectInset(self.bounds, CGFloat(15.0), CGFloat(15.0)) } override func drawRect(rect: CGRect) { super.drawTextInRect(CGRectInset(self.bounds,CGFloat(5.0), CGFloat(5.0))) } } 

类似于其他的答案,但用一个func类来设置填充dinamically:

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

一个实用的解决scheme是添加与主标签具有相同高度和颜色的空白标签。 将主标签的开头/结尾空格设置为零,alignment垂直中心,并将宽度设置为所需的边距。

没有子类化的另一种select是:

  1. 设置标签text
  2. sizeToFit()
  3. 然后稍微增加标签高度以模拟填充

     label.text = "someText" label.textAlignment = .center label.sizeToFit() label.frame = CGRect( x: label.frame.x, y: label.frame.y,width: label.frame.width + 20,height: label.frame.height + 8) 

如果你想在textRect周围添加2px的填充,只需要这样做:

 let insets = UIEdgeInsets(top: -2, left: -2, bottom: -2, right: -2) label.frame = UIEdgeInsetsInsetRect(textRect, insets) 

蒙迪的答案的详细说明。

即在UIViewembedded标签并通过自动布局实施填充。 例:

看起来像一个填充UILabel

概述:

1)创build一个UIView (“面板”),并设置其外观。

2)创build一个UILabel并将其添加到面板。

3)添加约束来强制填充。

4)将面板添加到您的视图层次结构,然后定位面板。

细节:

1)创build面板视图。

 let panel = UIView() panel.backgroundColor = .green panel.layer.cornerRadius = 12 

2)创build标签,将其作为子视图添加到面板。

 let label = UILabel() panel.addSubview(label) 

3)在标签的边缘和面板之间添加约束。 这迫使面板与标签保持一定的距离。 即“填充”

编辑:所有这些手工操作都非常繁琐,冗长而且容易出错。 我build议你从github中select一个Auto Layout包装器,或者自己写一个

 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 

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

注意:您只需要添加位置约束,而不是维度约束:自动布局将根据标签的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 

只需使用自动布局:

 let paddedWidth = myLabel.intrinsicContentSize.width + 2 * padding myLabel.widthAnchor.constraint(equalToConstant: paddedWidth).isActive = true 

完成。