Добавление пробела / дополнения в UILabel

У меня есть UILabel где я хочу добавить пространство сверху и снизу. С минимальной высотой в constrainst я изменил ее на:

введите описание изображения здесь

EDIT: для этого я использовал:

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

Но я должен найти другой метод, потому что, если я пишу более двух строк, проблема такая же:

введите описание изображения здесь

Если вы хотите придерживаться UILabel, без подкласса, Mundi дал вам четкое решение.

Если вы, наоборот, захотите обойти UILabel с UIView, вы можете использовать UITextView, чтобы включить использование UIEdgeInsets (дополнение) или подкласса UILabel для поддержки UIEdgeInsets.

Используя UITextView, вам нужно будет только предоставить вставки (OBJ-C):

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

Альтернативно, если вы подклассифицируете UILabel , примером этого подхода будет переопределение метода drawTextInRect
(OBJ-С)

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

Вы можете дополнительно предоставить вашему новому подклассу UILabel переменную вставки для TOP, LEFT, BOTTOM и RIGHT.

Пример кода может быть:

В .h (OBJ-C)

 float topInset, leftInset,bottomInset, rightInset; 

В .m (OBJ-C)

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

EDIT # 1:

Из того, что я видел, кажется, вам нужно переопределить intrinsicContentSize UILabel при подклассификации.

Поэтому вы должны переопределить 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

Я пробовал с ним, надеюсь, это сработает для вас!

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

Вы можете сделать это правильно от 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 } } } 

Просто используйте UIView в качестве супервизора и определите фиксированную маржу к метке с автоматической компоновкой.

SWIFT 3

Простое в использовании решение, доступное для всех детей 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() } 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 { get { var contentSize = super.intrinsicContentSize if let insets = padding { contentSize.height += insets.top + insets.bottom contentSize.width += insets.left + insets.right } return contentSize } } } 

Или, если вы предпочитаете подкласс:

 final class PaddedLabel: UILabel { var padding: UIEdgeInsets? override func draw(_ rect: CGRect) { if let insets = padding { self.drawText(in: UIEdgeInsetsInsetRect(rect, insets)) } else { self.drawText(in: rect) } } override var intrinsicContentSize: CGSize { get { var contentSize = super.intrinsicContentSize if let insets = padding { contentSize.height += insets.top + insets.bottom contentSize.width += insets.left + insets.right } 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-make Подкласс UILabel).

 // 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 на Storyboard в качестве класса Label.

Я немного отредактировал в принятом ответе. Возникает проблема, когда 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 } } 

и результат:

прописная метка с правильным внутренним размером содержимого

Я надеюсь помочь некоторым людям в той же ситуации, что и я.

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

Просто используйте 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 

Легкое дополнение (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 для динамического дополнения:

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

Одно прагматическое решение состоит в том, чтобы добавить пустые ярлыки той же высоты и цвета, что и основная метка. Установите ведущее / конечное пространство на основную метку равным нулю, выровняйте вертикальные центры и сделайте ширину нужного поля.

Другой вариант без подкласса – это:

  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) 

Просто используйте автозапуск:

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

Готово.

Interesting Posts
Давайте будем гением компьютера.