我有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))
}
但是我找到了一种不同的方法,因为如果我写两行以上,问题是一样的:
答案 0 :(得分:149)
我已尝试使用 Swift 4.2 ,希望它对您有用!
@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 drawText(in rect: CGRect) {
let insets = UIEdgeInsets(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset)
super.drawText(in: rect.inset(by: insets))
}
override var intrinsicContentSize: CGSize {
let size = super.intrinsicContentSize
return CGSize(width: size.width + leftInset + rightInset,
height: size.height + topInset + bottomInset)
}
}
或者你可以在这里使用CocoaPods https://github.com/levantAJ/PaddingLabel
pod 'PaddingLabel', '1.1'
答案 1 :(得分:94)
如果你想坚持使用UILabel而不进行子类化,Mundi已经给你一个明确的解决方案。
如果您愿意避免使用UIView包装UILabel,您可以使用UITextView来启用UIEdgeInsets(填充)或子类UILabel以支持UIEdgeInsets。
使用 UITextView ,您只需要提供插图(OBJ-C):
textView.textContainerInset = UIEdgeInsetsMake(10, 0, 10, 0);
替代方案,如果您继承 UILabel ,此方法的一个示例将覆盖 drawTextInRect 方法
(OBJ-C)
- (void)drawTextInRect:(CGRect)uiLabelRect {
UIEdgeInsets myLabelInsets = {10, 0, 10, 0};
[super drawTextInRect:UIEdgeInsetsInsetRect(uiLabelRect, myLabelInsets)];
}
您还可以为新的子类UILabel提供TOP,LEFT,BOTTOM和RIGHT的insets变量。
示例代码可以是:
在.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
搜索了一下之后,我发现了Gist和IPInsetLabel。如果这些解决方案都不起作用,您可以尝试一下。
编辑#3
关于这件事有类似的问题(重复) 有关可用解决方案的完整列表,请参阅以下答案: UILabel text margin
答案 2 :(得分:75)
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
}
}
}
答案 3 :(得分:65)
答案 4 :(得分:42)
SWIFT 4
易于使用的解决方案,适用于项目中的所有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: rect.inset(by: 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
var insetsWidth: CGFloat = 0.0
if let insets = padding {
insetsWidth += insets.left + insets.right
insetsHeight += insets.top + insets.bottom
textWidth -= insetsWidth
}
let newSize = text.boundingRect(with: CGSize(width: textWidth, height: CGFloat.greatestFiniteMagnitude),
options: NSStringDrawingOptions.usesLineFragmentOrigin,
attributes: [NSAttributedString.Key.font: self.font], context: nil)
contentSize.height = ceil(newSize.size.height) + insetsHeight
contentSize.width = ceil(newSize.size.width) + insetsWidth
return contentSize
}
}
答案 5 :(得分:37)
只需使用UIView
作为超级视图,并使用自动布局为标签定义固定边距。
答案 6 :(得分:27)
只需使用已经内置的UIButton。关闭所有额外的按钮功能,你就有了一个可以设置边缘文字的标签。
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
答案 7 :(得分:13)
没有故事板:
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)
答案 8 :(得分:8)
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()
}
}
不要忘记在storyboard标签对象中添加类名UIMarginLabel。 快乐的编码!
答案 9 :(得分:6)
根据 Swift 4.2 (Xcode 10 beta 6),已弃用“ UIEdgeInsetsInsetRect”。 我还宣布该类为公开课程,以使其更有用。
public class UIPaddedLabel: 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
public override func drawText(in rect: CGRect) {
let insets = UIEdgeInsets.init(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset)
super.drawText(in: rect.inset(by: insets))
}
public override var intrinsicContentSize: CGSize {
let size = super.intrinsicContentSize
return CGSize(width: size.width + leftInset + rightInset,
height: size.height + topInset + bottomInset)
}
public override func sizeToFit() {
super.sizeThatFits(intrinsicContentSize)
}
}
答案 10 :(得分:6)
Swift 3,iOS10解决方案:
def add_location_exe(request):
if request.method == 'POST':
ln = UserLocForm(request.POST or None)
if ln.is_valid():
name = ln.cleaned_data.get("name")
## is name in userloc list ##
答案 11 :(得分:5)
我在接受的答案中编辑了一点。 leftInset
和rightInset
增加时会出现问题,文本的一部分会消失,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
}
}
和结果:
我希望能帮助处理与我相同情况的人。
答案 12 :(得分:5)
UILabel子类。 (File-New-File-CocoaTouchClass-make Ucabel的子类)。
// 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)
}
或者将故事板上的自定义UILabel类关联为Label的类。
答案 13 :(得分:3)
在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))
}
}
答案 14 :(得分:3)
只需使用autolayout:
let paddedWidth = myLabel.intrinsicContentSize.width + 2 * padding
myLabel.widthAnchor.constraint(equalToConstant: paddedWidth).isActive = true
完成。
答案 15 :(得分:3)
快速4 +
class EdgeInsetLabel: UILabel {
var textInsets = UIEdgeInsets.zero {
didSet { invalidateIntrinsicContentSize() }
}
override func textRect(forBounds bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect {
let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines)
let invertedInsets = UIEdgeInsets(top: -textInsets.top,
left: -textInsets.left,
bottom: -textInsets.bottom,
right: -textInsets.right)
return textRect.inset(by: invertedInsets)
}
override func drawText(in rect: CGRect) {
super.drawText(in: rect.inset(by: textInsets))
}
}
用法:
let label = EdgeInsetLabel()
label.textInsets = UIEdgeInsets(top: 2, left: 6, bottom: 2, right: 6)
答案 16 :(得分:2)
没有子类化的另一个选择是:
text
sizeToFit()
然后稍微增加标签高度以模拟填充
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)
答案 17 :(得分:2)
详细阐述了Mundi的答案。
即。在UIView
中嵌入标签并通过自动布局强制执行填充。例如:
<强>概述:强>
1)创建UIView
(&#34;面板&#34;),并设置其外观。
2)创建UILabel
并将其添加到面板。
3)添加约束以强制填充。
4)将面板添加到视图层次结构中,然后定位面板。
<强>详细信息:强>
1)创建面板视图。
let panel = UIView()
panel.backgroundColor = .green
panel.layer.cornerRadius = 12
2)创建标签,将其作为子视图添加到面板中。
let label = UILabel()
panel.addSubview(label)
3)在标签边缘和面板之间添加约束。这会强制面板与标签保持一定距离。即&#34;填充&#34;
编辑:手工完成这一切是非常乏味,冗长和容易出错的。我建议你从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
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
答案 18 :(得分:2)
轻松填充(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)))
}
}
答案 19 :(得分:2)
就像其他答案一样,但修复了一个错误。
通过自动布局控制@IBDesignable
class InsetLabel: UILabel {
@IBInspectable var topInset: CGFloat = 4.0
@IBInspectable var leftInset: CGFloat = 4.0
@IBInspectable var bottomInset: CGFloat = 4.0
@IBInspectable var rightInset: CGFloat = 4.0
var insets: UIEdgeInsets {
get {
return UIEdgeInsets.init(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset)
}
set {
topInset = newValue.top
leftInset = newValue.left
bottomInset = newValue.bottom
rightInset = newValue.right
}
}
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 {
let systemContentSize = super.intrinsicContentSize
let adjustSize = CGSize(width: systemContentSize.width + leftInset + rightInset, height: systemContentSize.height + topInset + bottomInset)
if adjustSize.width > preferredMaxLayoutWidth && preferredMaxLayoutWidth != 0 {
let constraintSize = CGSize(width: bounds.width - (leftInset + rightInset), height: .greatestFiniteMagnitude)
let newSize = super.sizeThatFits(constraintSize)
return CGSize(width: systemContentSize.width, height: ceil(newSize.height) + topInset + bottomInset)
} else {
return adjustSize
}
}
override func drawText(in rect: CGRect) {
super.drawText(in: rect.inset(by: insets))
}
}
时,有时会裁切文本。
outputPaths: {
app: {
css: {
app: '/assets/custom-name.css'
}
}
},
答案 20 :(得分:1)
与其他答案类似,但使用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))
}
}
答案 21 :(得分:1)
事实证明,必须完成三件事。
在此典型示例中,文本单元处于表格视图,堆栈视图或类似的结构中,从而赋予其固定宽度。在示例中,我们希望填充为60、20、20、24。
因此,我们采用“现有的” internalContentSize ,实际上将高度增加了80 。
您必须从字面上“获取”由引擎“到目前为止”计算出的高度,然后更改该值。
我发现这令人困惑,但这就是它的工作原理。对我来说,Apple应该公开一个名为“初步高度计算”的呼叫。
第二,我们必须实际使用具有较小尺寸的textRect#forBounds呼叫 。
因此,在textRect#forBounds中,我们首先 使尺寸变小,然后 然后 调用超级。
此页面上只有几个答案接近有效:以前我们使用@ LE24给出的模式。但这就是确切的问题-您必须先在textRect#forBounds中调整大小,然后再调用super。
如果您以错误的方式进行操作,通常会起作用,但不适用于某些特定的文本长度。这是“不正确地做超级第一”的示例:
请注意60,20,20,24页边距是正确的,但是大小计算实际上是错误的,因为它是使用textRect#forBounds中的“超级第一”模式完成的。
已修复:
现在只有textRect#forBounds引擎知道如何正确执行计算:
最后!
同样,在此示例中,UILabel在宽度固定的典型情况下使用。因此,在internalContentSize中,我们必须“添加”所需的总体额外高度。 (您不需要以任何方式在宽度上“添加”,因为它是固定的,所以毫无意义。)
然后在textRect#forBounds中,通过自动布局获得“建议的边界”,您 减去 边距, 然后仅此 再次调用textRect#forBounds引擎,换句话说就是super,它将为您提供结果。
最后,在drawText中,您当然会在同一较小的框中绘制。
Ph!
let UIEI = UIEdgeInsets(top: 60, left: 20, bottom: 20, right: 24)
override var intrinsicContentSize:CGSize {
numberOfLines = 0 // don't forget!
var s = super.intrinsicContentSize
s.height = s.height + 60.0 + 20.0
return s
}
override func drawText(in rect:CGRect) {
let r = rect.inset(by: UIEI)
super.drawText(in: r)
}
override func textRect(forBounds bounds:CGRect,
limitedToNumberOfLines n:Int) -> CGRect {
let b = bounds
let tr = b.inset(by: UIEI)
let ctr = super.textRect(forBounds: tr, limitedToNumberOfLines: 0)
return ctr
}
再次。请注意,此和其他QA上“几乎”正确的答案在上面的第一张图片中遇到了问题- “ super的位置不正确” 。您必须在internalContentSize中强制增大大小,然后在 必须首先 的textRect#forBounds中将其缩小,首先缩小建议范围 ,然后 < / strong>叫超级。
那是秘密。
请注意,您不需要也不需要另外调用invalidate,sizeThatFits,needsLayout或任何其他强制调用。正确的解决方案应在正常的自动布局绘制循环中正常工作。
答案 22 :(得分:1)
Objective-C
基于此处的Tai Le答案,该答案实现了IB Designable内部的功能,这是Objective-C版本。
将此内容放入YourLabel.h
@interface YourLabel : UILabel
@property IBInspectable CGFloat topInset;
@property IBInspectable CGFloat bottomInset;
@property IBInspectable CGFloat leftInset;
@property IBInspectable CGFloat rightInset;
@end
这将放在YourLabel.m
IB_DESIGNABLE
@implementation YourLabel
#pragma mark - Super
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
self.topInset = 0;
self.bottomInset = 0;
self.leftInset = 0;
self.rightInset = 0;
}
return self;
}
- (void)drawTextInRect:(CGRect)rect {
UIEdgeInsets insets = UIEdgeInsetsMake(self.topInset, self.leftInset, self.bottomInset, self.rightInset);
[super drawTextInRect:UIEdgeInsetsInsetRect(rect, insets)];
}
- (CGSize)intrinsicContentSize {
CGSize size = [super intrinsicContentSize];
return CGSizeMake(size.width + self.leftInset + self.rightInset,
size.height + self.topInset + self.bottomInset);
}
@end
然后,您可以在XIB或情节提要中指定类后直接在Interface Builder中修改YourLabel插图,这些插图的默认值为零。
答案 23 :(得分:1)
对于任何只需要在严格单行标签(例如节标题或其他列表项)上填充的人来说,
语法发生了很大变化。这是要复制和粘贴的确切类:
// add 100 above, 50 padding below a SINGLE-LINE label
import UIKit
class SingleLineLabelWithSpacing: UILabel {
// STRICTLY for SINGLE LINE labels
// only works with SINGLE LINE labels
override func drawText(in rect: CGRect) {
let insets: UIEdgeInsets = UIEdgeInsets(
top: 100, left: 0, bottom: 50, right: 0)
super.drawText(in: rect.inset(by: insets))
}
override var intrinsicContentSize: CGSize {
var ic = super.intrinsicContentSize
ic.height = ic.height + 150
return ic
}
}
注意 100/50 以上/以下的填充。
当您有任何类型的滚动列表、提要或其他列表时,这是通常的做法。
通过这种方式,您无需考虑标题上方/下方的间距、用户名等 - 您只需将其放在堆栈视图中或其他任何情况下即可。
当然,当设计师想要调整时,您也可以在任何地方一次性更改这两个值。
提醒:如果你想真正地填充一个 UILabel 以便它完美地工作而不管文本的行数、动态调整单元格等等等等,这是非常复杂的。正确答案在“适用于所有情况的完整正确解决方案”下方。
答案 24 :(得分:1)
如果您不想或不需要在Storyboard中使用@IBInspectable / @IBDesignable UILabel(我认为它们渲染得太慢了),那么使用UIEdgeInsets而不是4种不同的CGFloats会更干净。
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)
}
}
答案 25 :(得分:1)
如果要在textRect周围添加2px填充,只需执行以下操作:
let insets = UIEdgeInsets(top: -2, left: -2, bottom: -2, right: -2)
label.frame = UIEdgeInsetsInsetRect(textRect, insets)
答案 26 :(得分:1)
简单方法
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.
}
}
答案 27 :(得分:0)
如果您想使用 UILabel
class UILabel : UIKit.UILabel {
var insets = UIEdgeInsets.zero {
didSet { invalidateIntrinsicContentSize() }
}
override func textRect(forBounds bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect {
let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines)
let invertedInsets = UIEdgeInsets(top: -insets.top,
left: -insets.left,
bottom: -insets.bottom,
right: -insets.right)
return textRect.inset(by: invertedInsets)
}
override func drawText(in rect: CGRect) {
super.drawText(in: rect.inset(by: insets))
}
}
答案 28 :(得分:0)
一个实用的解决方案是添加与主标签具有相同高度和颜色的空白标签。将主标签的前/后空格设置为零,对齐垂直中心,并使宽度成为所需的边距。
答案 29 :(得分: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.
答案 30 :(得分:0)
使用下面的代码来设置边距就像label.setMargins(15)
一样容易。
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
}
}
}
答案 31 :(得分:0)
我的解决方案类似于人们的回答,但是添加了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
}
}
答案 32 :(得分:0)
UILabel,在 Swift 5,XCode 11 中,顶部,底部,左侧或右侧具有填充。 Fattie的The great answer经过一些改进后转换为Swift 5。
import UIKit
enum PaddingLabelSpace {
case none
case topBy4
case topBy8
case topBy16
case topBy24
case topBy32
case bottomBy4
case bottomBy8
case bottomBy16
case bottomBy24
case bottomBy32
case spaceBy4
case spaceBy8
case spaceBy16
case spaceBy24
case spaceBy32
case spaceVerticallyBy4
case spaceVerticallyBy8
case spaceVerticallyBy16
case spaceVerticallyBy24
case spaceVerticallyBy32
case spaceHorizontallyBy4
case spaceHorizontallyBy8
case spaceHorizontallyBy16
case spaceHorizontallyBy24
case spaceHorizontallyBy32
}
extension PaddingLabelSpace {
var padding: UIEdgeInsets {
switch self {
case .none: return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
case .spaceVerticallyBy4: return UIEdgeInsets(top: 0, left: 4, bottom: 0, right: 4)
case .spaceVerticallyBy8: return UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8)
case .spaceVerticallyBy16: return UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
case .spaceVerticallyBy24: return UIEdgeInsets(top: 0, left: 24, bottom: 0, right: 24)
case .spaceVerticallyBy32: return UIEdgeInsets(top: 0, left: 32, bottom: 0, right: 32)
case .spaceHorizontallyBy4: return UIEdgeInsets(top: 4, left: 0, bottom: 4, right: 0)
case .spaceHorizontallyBy8: return UIEdgeInsets(top: 8, left: 0, bottom: 8, right: 0)
case .spaceHorizontallyBy16: return UIEdgeInsets(top: 16, left: 0, bottom: 16, right: 0)
case .spaceHorizontallyBy24: return UIEdgeInsets(top: 24, left: 0, bottom: 24, right: 0)
case .spaceHorizontallyBy32: return UIEdgeInsets(top: 32, left: 0, bottom: 32, right: 0)
case .spaceBy4: return UIEdgeInsets(top: 4, left: 4, bottom: 4, right: 4)
case .spaceBy8: return UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
case .spaceBy16: return UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
case .spaceBy24: return UIEdgeInsets(top: 24, left: 24, bottom: 24, right: 24)
case .spaceBy32: return UIEdgeInsets(top: 32, left: 32, bottom: 32, right: 32)
case .topBy4: return UIEdgeInsets(top: 4, left: 0, bottom: 0, right: 0)
case .topBy8: return UIEdgeInsets(top: 8, left: 0, bottom: 0, right: 0)
case .topBy16: return UIEdgeInsets(top: 16, left: 0, bottom: 0, right: 0)
case .topBy24: return UIEdgeInsets(top: 24, left: 0, bottom: 0, right: 0)
case .topBy32: return UIEdgeInsets(top: 32, left: 0, bottom: 0, right: 0)
case .bottomBy4: return UIEdgeInsets(top: 0, left: 0, bottom: 4, right: 0)
case .bottomBy8: return UIEdgeInsets(top: 0, left: 0, bottom: 8, right: 0)
case .bottomBy16: return UIEdgeInsets(top: 0, left: 0, bottom: 16, right: 0)
case .bottomBy24: return UIEdgeInsets(top: 0, left: 0, bottom: 24, right: 0)
case .bottomBy32: return UIEdgeInsets(top: 0, left: 0, bottom: 32, right: 0)
}
}
}
class PaddingLabel: UILabel {
var topInset: CGFloat = 0.0
var bottomInset: CGFloat = 0.0
var leftInset: CGFloat = 16.0
var rightInset: CGFloat = 16.0
override var intrinsicContentSize:CGSize {
numberOfLines = 0 // don't forget!
var s = super.intrinsicContentSize
s.height = s.height + topInset + bottomInset
return s
}
override func drawText(in rect:CGRect) {
let r = rect.inset(by: UIEdgeInsets(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset))
super.drawText(in: r)
}
override func textRect(forBounds bounds:CGRect,
limitedToNumberOfLines n:Int) -> CGRect {
let b = bounds
let tr = b.inset(by: UIEdgeInsets(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset))
let ctr = super.textRect(forBounds: tr, limitedToNumberOfLines: 0)
return ctr
}
func setPadding(paddingSpace: PaddingLabelSpace){
self.topInset = paddingSpace.padding.top
self.bottomInset = paddingSpace.padding.bottom
self.leftInset = paddingSpace.padding.left
self.rightInset = paddingSpace.padding.right
let insets: UIEdgeInsets = UIEdgeInsets(top: paddingSpace.padding.top, left: paddingSpace.padding.left, bottom: paddingSpace.padding.bottom, right: paddingSpace.padding.right)
super.drawText(in: self.frame.inset(by: insets))
}
func setPadding(paddingWithEdgeInsets: UIEdgeInsets){
self.topInset = paddingWithEdgeInsets.top
self.bottomInset = paddingWithEdgeInsets.bottom
self.leftInset = paddingWithEdgeInsets.left
self.rightInset = paddingWithEdgeInsets.right
let insets: UIEdgeInsets = paddingWithEdgeInsets
super.drawText(in: self.frame.inset(by: insets))
}
}
使用方法:
1)将您的IBOutlet设置为PaddingLabel
@IBOutlet weak var userBioLabel: PaddingLabel!
2)设置填充
self.userBioLabel.setPadding(paddingSpace: .spaceVerticallyBy16)
或
let UIEI = UIEdgeInsets(top: 3, left: 9, bottom: 3, right: 9)
self.userBioLabel.setPadding(paddingWithEdgeInsets: UIEI)
答案 33 :(得分:0)
轻松填充
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)))
}
}
答案 34 :(得分:-1)
雨燕5
在方法layoutSubviews()上,将UILabel的插入内容更改为以下行。
override func layoutSubviews() {
super.layoutSubviews()
label.frame = label.frame.inset(by: UIEdgeInsets(top: 5, left: 10, bottom: 5, right: 10))
}
答案 35 :(得分:-1)
快速4 +
contentType: "application/x-www-form-urlencoded"
答案 36 :(得分:-4)