30 ответов:
я решил это путем создания подклассов
UILabelи переопределитьdrawTextInRect:такой:- (void)drawTextInRect:(CGRect)rect { UIEdgeInsets insets = {0, 5, 0, 5}; [super drawTextInRect:UIEdgeInsetsInsetRect(rect, insets)]; }эквивалент в Swift 3.1:
override func drawText(in rect: CGRect) { let insets = UIEdgeInsets.init(top: 0, left: 5, bottom: 0, right: 5) super.drawText(in: UIEdgeInsetsInsetRect(rect, insets)) }как вы могли бы догадаться, это адаптация tc.'ы ответ. Он имеет два преимущества по сравнению с этим:
- там нет необходимости, чтобы вызвать его, направив
sizeToFit- он оставляет рамку метки в покое-удобно, если ваша метка имеет фон, и вы не хотите, чтобы это термоусадочные
для многострочного текста левое и правое поля можно задать с помощью NSAttributedString.
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; style.alignment = NSTextAlignmentJustified; style.firstLineHeadIndent = 10.0f; style.headIndent = 10.0f; style.tailIndent = -10.0f; NSAttributedString *attrText = [[NSAttributedString alloc] initWithString:title attributes:@{ NSParagraphStyleAttributeName : style}]; UILabel * label = [[UILabel alloc] initWithFrame:someFrame]; label.numberOfLines = 0; label.attributedText = attrText;
лучший способ добавить дополнение к UILabel-это подкласс UILabel и добавить свойство edgeInsets. Затем вы устанавливаете нужные вставки, и метка будет нарисована соответствующим образом.
OSLabel.h
#import <UIKit/UIKit.h> @interface OSLabel : UILabel @property (nonatomic, assign) UIEdgeInsets edgeInsets; @endOSLabel.м
#import "OSLabel.h" @implementation OSLabel - (id)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { self.edgeInsets = UIEdgeInsetsMake(0, 0, 0, 0); } return self; } - (void)drawTextInRect:(CGRect)rect { [super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.edgeInsets)]; } - (CGSize)intrinsicContentSize { CGSize size = [super intrinsicContentSize]; size.width += self.edgeInsets.left + self.edgeInsets.right; size.height += self.edgeInsets.top + self.edgeInsets.bottom; return size; } @end
подклассы немного громоздки для такого простого случая. В качестве альтернативы можно просто добавить UILabel ни при Нет фоновых значение в UIView с фоновой набор. Установите x метки на 10 и сделайте размер внешнего вида на 10 пикселей шире, чем метка.
Я закончил тем, что просто добавил некоторые пробелы в текст:
self.titleLabel.text = [NSString stringWithFormat:@" %@", self.titleLabel.text];уродливый, но эффективный, и не требуется подклассов.
вы также можете попробовать "\t". Для общего решения, пожалуйста, обратитесь к принятому ответу
С помощью Swift 3 Вы можете получить желаемый эффект, создав подкласс
UILabel. В этом подклассе вам нужно будет добавитьUIEdgeInsetsсвойство с необходимыми вставками и переопределениемdrawText(in:)методintrinsicContentSizeсвойство (для кода автоматической компоновки) и / илиsizeThatFits(_:)метод (для кода пружин и стоек).import UIKit class PaddingLabel: UILabel { let padding: UIEdgeInsets // Create a new PaddingLabel instance programamtically with the desired insets required init(padding: UIEdgeInsets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10)) { self.padding = padding super.init(frame: CGRect.zero) } // Create a new PaddingLabel instance programamtically with default insets override init(frame: CGRect) { padding = UIEdgeInsets.zero // set desired insets value according to your needs super.init(frame: frame) } // Create a new PaddingLabel instance from Storyboard with default insets required init?(coder aDecoder: NSCoder) { padding = UIEdgeInsets.zero // set desired insets value according to your needs super.init(coder: aDecoder) } override func drawText(in rect: CGRect) { super.drawText(in: UIEdgeInsetsInsetRect(rect, padding)) } // Override `intrinsicContentSize` property for Auto layout code override var intrinsicContentSize: CGSize { let superContentSize = super.intrinsicContentSize let width = superContentSize.width + padding.left + padding.right let heigth = superContentSize.height + padding.top + padding.bottom return CGSize(width: width, height: heigth) } // Override `sizeThatFits(_:)` method for Springs & Struts code override func sizeThatFits(_ size: CGSize) -> CGSize { let superSizeThatFits = super.sizeThatFits(size) let width = superSizeThatFits.width + padding.left + padding.right let heigth = superSizeThatFits.height + padding.top + padding.bottom return CGSize(width: width, height: heigth) } }в следующем примере показано, как использовать
PaddingLabelэкземпляровUIViewController:import UIKit class ViewController: UIViewController { @IBOutlet weak var storyboardAutoLayoutLabel: PaddingLabel! let autoLayoutLabel = PaddingLabel(padding: UIEdgeInsets(top: 20, left: 40, bottom: 20, right: 40)) let springsAndStructsLabel = PaddingLabel(frame: CGRect.zero) var textToDisplay = "Lorem ipsum dolor sit er elit lamet." override func viewDidLoad() { super.viewDidLoad() // Set autoLayoutLabel autoLayoutLabel.text = textToDisplay autoLayoutLabel.backgroundColor = .red autoLayoutLabel.translatesAutoresizingMaskIntoConstraints = false view.addSubview(autoLayoutLabel) autoLayoutLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30).isActive = true autoLayoutLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true // Set springsAndStructsLabel springsAndStructsLabel.text = textToDisplay springsAndStructsLabel.backgroundColor = .green view.addSubview(springsAndStructsLabel) springsAndStructsLabel.frame.origin = CGPoint(x: 30, y: 90) springsAndStructsLabel.sizeToFit() // Set storyboardAutoLayoutLabel storyboardAutoLayoutLabel.text = textToDisplay storyboardAutoLayoutLabel.backgroundColor = .blue } // Link this IBAction to a UIButton or a UIBarButtonItem in Storyboard @IBAction func updateLabelText(_ sender: Any) { textToDisplay = textToDisplay == "Lorem ipsum dolor sit er elit lamet." ? "Lorem ipsum." : "Lorem ipsum dolor sit er elit lamet." // autoLayoutLabel autoLayoutLabel.text = textToDisplay // springsAndStructsLabel springsAndStructsLabel.text = textToDisplay springsAndStructsLabel.sizeToFit() // storyboardAutoLayoutLabel storyboardAutoLayoutLabel.text = textToDisplay } }
быстрая версия ответа переработанной стали +
intrinsizeContentSize().Он поддерживает более традиционный стиль установки вставок для других объектов представления с вставками, имея возможность устанавливать вставки в Interface Builder, т. е. вставки устанавливаются так программно:
label.inset = UIEdgeInsetsMake(0, 0, 5, 0)пожалуйста, дайте мне знать, если есть какие-либо ошибки.
Swift 3
@IBDesignable class InsetLabel: UILabel { @IBInspectable var topInset: CGFloat = 0.0 @IBInspectable var leftInset: CGFloat = 0.0 @IBInspectable var bottomInset: CGFloat = 0.0 @IBInspectable var rightInset: CGFloat = 0.0 var insets: UIEdgeInsets { get { return UIEdgeInsetsMake(topInset, leftInset, bottomInset, rightInset) } set { topInset = newValue.top leftInset = newValue.left bottomInset = newValue.bottom rightInset = newValue.right } } override func drawText(in rect: CGRect) { super.drawText(in: UIEdgeInsetsInsetRect(rect, insets)) } 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 { var contentSize = super.intrinsicContentSize contentSize.width += leftInset + rightInset contentSize.height += topInset + bottomInset return contentSize } }Swift 2.2
@IBDesignable class InsetLabel: UILabel { @IBInspectable var topInset: CGFloat = 0.0 @IBInspectable var leftInset: CGFloat = 0.0 @IBInspectable var bottomInset: CGFloat = 0.0 @IBInspectable var rightInset: CGFloat = 0.0 var insets: UIEdgeInsets { get { return UIEdgeInsetsMake(topInset, leftInset, bottomInset, rightInset) } set { topInset = newValue.top leftInset = newValue.left bottomInset = newValue.bottom rightInset = newValue.right } } override func drawTextInRect(rect: CGRect) { super.drawTextInRect(UIEdgeInsetsInsetRect(rect, insets)) } override func sizeThatFits(size: CGSize) -> CGSize { var adjSize = super.sizeThatFits(size) adjSize.width += leftInset + rightInset adjSize.height += topInset + bottomInset return adjSize } override func intrinsicContentSize() -> CGSize { var contentSize = super.intrinsicContentSize() contentSize.width += leftInset + rightInset contentSize.height += topInset + bottomInset return contentSize } }
вы также можете решить эту проблему, инициализировав свой UILabel с помощью пользовательского фрейма.
CGRect initialFrame = CGRectMake(0, 0, 100, 100); UIEdgeInsets contentInsets = UIEdgeInsetsMake(0, 10, 0, 0); CGRect paddedFrame = UIEdgeInsetsInsetRect(initialFrame, contentInsets); self.label = [[UILabel alloc] initWithFrame:paddedFrame];кивать CGRect Трюки.
для пользователей Xamarin (с использованием унифицированного API):
class UIMarginLabel : UILabel { public UIMarginLabel() { } public UIMarginLabel( RectangleF frame ) : base( frame ) { } public UIEdgeInsets Insets { get; set; } public override void DrawText( CGRect rect ) { base.DrawText( Insets.InsetRect( rect ) ); } }и для тех, кто использует оригинальный MonoTouch API:
public class UIMarginLabel : UILabel { public UIEdgeInsets Insets { get; set; } public UIMarginLabel() : base() { Insets = new UIEdgeInsets(0, 0, 0, 0); } public UIMarginLabel(RectangleF frame) : base(frame) { Insets = new UIEdgeInsets(0, 0, 0, 0); } public override void DrawText(RectangleF frame) { base.DrawText(new RectangleF( frame.X + Insets.Left, frame.Y + Insets.Top, frame.Width - Insets.Left - Insets.Right, frame.Height - Insets.Top - Insets.Bottom)); } }
чтобы расширить ответ, предоставленный Броди Робертсоном, вы можете добавить биты IB Designable. Это означает, что вы можете настроить метки в раскадровке.
в вашем подклассе UILabel do
#import <UIKit/UIKit.h> IB_DESIGNABLE @interface insetLabel : UILabel @property (nonatomic, assign) IBInspectable CGFloat leftEdge; @property (nonatomic, assign) IBInspectable CGFloat rightEdge; @property (nonatomic, assign) IBInspectable CGFloat topEdge; @property (nonatomic, assign) IBInspectable CGFloat bottomEdge; @property (nonatomic, assign) UIEdgeInsets edgeInsets; @endпотом делать;
#import "insetLabel.h" @implementation insetLabel - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.edgeInsets = UIEdgeInsetsMake(self.topEdge, self.leftEdge, self.bottomEdge, self.rightEdge); } return self; } - (void)drawTextInRect:(CGRect)rect { self.edgeInsets = UIEdgeInsetsMake(self.topEdge, self.leftEdge, self.bottomEdge, self.rightEdge); [super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.edgeInsets)]; } - (CGSize)intrinsicContentSize { CGSize size = [super intrinsicContentSize]; size.width += self.edgeInsets.left + self.edgeInsets.right; size.height += self.edgeInsets.top + self.edgeInsets.bottom; return size; } @endредактировать
вероятно, вам следует добавить метод setter для edgeInsets.
и @IBDesignable, которые заставляют его работать с Interface Builder
@IBDesignable class PaddedLabel: UILabel { @IBInspectable var inset:CGSize = CGSize(width: 0, height: 0) var padding: UIEdgeInsets { var hasText:Bool = false if let t = text?.length where t > 0 { hasText = true } else if let t = attributedText?.length where t > 0 { hasText = true } return hasText ? UIEdgeInsets(top: inset.height, left: inset.width, bottom: inset.height, right: inset.width) : UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) } override func drawTextInRect(rect: CGRect) { super.drawTextInRect(UIEdgeInsetsInsetRect(rect, padding)) } override func intrinsicContentSize() -> CGSize { let superContentSize = super.intrinsicContentSize() let p = padding let width = superContentSize.width + p.left + p.right let heigth = superContentSize.height + p.top + p.bottom return CGSize(width: width, height: heigth) } override func sizeThatFits(size: CGSize) -> CGSize { let superSizeThatFits = super.sizeThatFits(size) let p = padding let width = superSizeThatFits.width + p.left + p.right let heigth = superSizeThatFits.height + p.top + p.bottom return CGSize(width: width, height: heigth) } }
Если вы не хотите использовать дополнительный Родительский вид для установки фона, вы можете подкласс UILabel и переопределить
textRectForBounds:limitedToNumberOfLines:. Я бы добавил свойство textEdgeInsets или подобное, а затем сделал- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines { return [super textRectForBounds:UIEdgeInsetsInsetRect(bounds,textEdgeInsets) limitedToNumberOfLines:numberOfLines]; }для надежности вы также можете вызвать [self setNeedsDisplay] в setTextEdgeInsets:, но я обычно не беспокоюсь.
может быть, позже для партии, но следующее просто работает. Просто подкласс UILabel.
#import "UITagLabel.h" #define padding UIEdgeInsetsMake(5, 10, 5, 10) @implementation UITagLabel - (void)drawTextInRect:(CGRect)rect { [super drawTextInRect:UIEdgeInsetsInsetRect(rect, padding)]; } - (CGSize) intrinsicContentSize { CGSize superContentSize = [super intrinsicContentSize]; CGFloat width = superContentSize.width + padding.left + padding.right; CGFloat height = superContentSize.height + padding.top + padding.bottom; return CGSizeMake(width, height); } - (CGSize) sizeThatFits:(CGSize)size { CGSize superSizeThatFits = [super sizeThatFits:size]; CGFloat width = superSizeThatFits.width + padding.left + padding.right; CGFloat height = superSizeThatFits.height + padding.top + padding.bottom; return CGSizeMake(width, height); } @end
Если вы используете autolayout в iOS 6+, Вы можете сделать это, настроив
intrinsicContentSizeв подклассеUILabel.- (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.textAlignment = NSTextAlignmentRight; } return self; } - (CGSize)intrinsicContentSize { CGSize size = [super intrinsicContentSize]; return CGSizeMake(size.width + 10.0, size.height); }
вот быстрое решение. Просто добавьте этот пользовательский класс в нижней части файла (или создайте для него новый файл) и используйте MyLabel вместо UILabel при создании метки.
class MyLabel: UILabel{ override func drawTextInRect(rect: CGRect) { super.drawTextInRect(UIEdgeInsetsInsetRect(rect, UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 0))) } }
вместо UILabel возможно использовать https://github.com/mattt/TTTAttributedLabel
BITAttributedLabel *label = [BITAttributedLabel new]; label.font = font; label.text = @"hello"; label.textInsets = UIEdgeInsetsMake(10, 10, 10, 10); [label sizeToFit];
в Swift он решает так.
class Label: UILabel { override func drawTextInRect(rect: CGRect) { super.drawTextInRect(UIEdgeInsetsInsetRect(rect, UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10))) } }
во многих ответах отсутствует переопределение sizeThatFits. С помощью этого подкласса вы можете просто создать метку, установить заполнение, а затем сказать label.SizeToFit() и вуаля.
import UIKit class UILabelEx : UILabel { var padding : UIEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) override func drawTextInRect(rect: CGRect) { super.drawTextInRect(UIEdgeInsetsInsetRect(rect, padding)) } override func sizeThatFits(size: CGSize) -> CGSize { var adjSize = super.sizeThatFits(size) adjSize.width += padding.left + padding.right adjSize.height += padding.top + padding.bottom return adjSize } }
asnwer blyabtroi преобразуется в Swift (не требуется подклассов)
let style: NSMutableParagraphStyle = NSParagraphStyle.defaultParagraphStyle().mutableCopy() as! NSMutableParagraphStyle style.alignment = .Justified style.firstLineHeadIndent = 10.0 style.headIndent = 10.0 style.tailIndent = -10.0 let attrText: NSAttributedString = NSAttributedString(string: title, attributes: [NSParagraphStyleAttributeName:style]) let label: UILabel = UILabel(frame: someFrame) label.numberOfLines = 0 label.attributedText = attrText
это работает правильно с многострочными метками:
class PaddedLabel: UILabel { var verticalPadding: CGFloat = 0 var horizontalPadding: CGFloat = 0 override func drawText(in rect: CGRect) { let insets = UIEdgeInsets(top: verticalPadding, left: horizontalPadding, bottom: verticalPadding, right: horizontalPadding) super.drawText(in: UIEdgeInsetsInsetRect(rect, insets)) } override var intrinsicContentSize: CGSize { get { let textWidth = super.intrinsicContentSize.width - horizontalPadding * 2 let textHeight = sizeThatFits(CGSize(width: textWidth, height: .greatestFiniteMagnitude)).height let width = textWidth + horizontalPadding * 2 let height = textHeight + verticalPadding * 2 return CGSize(width: frame.width, height: height) } } }
решение Xcode 6.1.1 Swift с использованием расширения.
имя файла может быть что-то вроде "UILabel+AddInsetMargin.Свифт":
import UIKit extension UILabel { public override func drawRect(rect: CGRect) { self.drawTextInRect(UIEdgeInsetsInsetRect(rect, UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5))) } }
без подклассов и всего этого джаза.. я сделал это динамически:
[cell.textLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; [cell.textLabel constraintTrailingEqualTo:cell.contentView constant:-100];ограничительная часть-это просто простая оболочка сахара кода (у нас есть те же методы для добавления заполнения сверху/снизу/слева/справа).. я открою исходный код всей обертки, если я получу достаточно любви здесь:
- (id)constraintTrailingEqualTo:(UIView *)toView constant:(CGFloat)constant { NSLayoutConstraint *cn = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:toView attribute:NSLayoutAttributeTrailing multiplier:1 constant:constant]; [toView addConstraint:cn]; return self; }(заметьте, я сделал это в контексте
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath;возможно, вам придется позвонить
[self setNeedsLayout];в зависимости от вашего контекста.
#import "E_LabelWithPadding.h" #define padding UIEdgeInsetsMake(2, 0, 2, 0) #define padding1 UIEdgeInsetsMake(0, 0, 0, 0) @implementation E_LabelWithPadding - (void)drawTextInRect:(CGRect)rect { if (![self.text isEqualToString:@""]) { [super drawTextInRect:UIEdgeInsetsInsetRect(rect, padding)]; }else { [super drawTextInRect:UIEdgeInsetsInsetRect(rect, padding1)]; }}
- (CGSize) intrinsicContentSize { if (![self.text isEqualToString:@""]) { CGSize superContentSize = [super intrinsicContentSize]; CGFloat width = superContentSize.width + padding.left + padding.right; CGFloat height = superContentSize.height + padding.top + padding.bottom; return CGSizeMake(width, height); }else { CGSize superContentSize = [super intrinsicContentSize]; CGFloat width = superContentSize.width + padding1.left + padding1.right; CGFloat height = superContentSize.height + padding1.top + padding1.bottom; return CGSizeMake(width, height); }}
- (CGSize) sizeThatFits:(CGSize)size { if (![self.text isEqualToString:@""]) { CGSize superSizeThatFits = [super sizeThatFits:size]; CGFloat width = superSizeThatFits.width + padding.left + padding.right; CGFloat height = superSizeThatFits.height + padding.top + padding.bottom; return CGSizeMake(width, height); }else { CGSize superSizeThatFits = [super sizeThatFits:size]; CGFloat width = superSizeThatFits.width + padding1.left + padding1.right; CGFloat height = superSizeThatFits.height + padding1.top + padding1.bottom; return CGSizeMake(width, height); }}
@end
просто добавьте пробелы слева если это одна строка, более чем 1 строка будет иметь 0 отступов снова.
[self.myLabel setText:[NSString stringWithFormat:@" %@", self.myShortString]];
Swift 3 & AutoLayout совместимость версия:
class InsetLabel: UILabel { var insets = UIEdgeInsets() convenience init(insets: UIEdgeInsets) { self.init(frame: CGRect.zero) self.insets = insets } convenience init(dx: CGFloat, dy: CGFloat) { let insets = UIEdgeInsets(top: dy, left: dx, bottom: dy, right: dx) self.init(insets: insets) } override func drawText(in rect: CGRect) { super.drawText(in: UIEdgeInsetsInsetRect(rect, insets)) } override var intrinsicContentSize: CGSize { var size = super.intrinsicContentSize size.width += insets.left + insets.right size.height += insets.top + insets.bottom return size } }
Я думаю
UILabelкласс не имеет метода для установки маржи. Почему вы не устанавливаете положение ярлыка на необходимом месте?ниже код:
UILabel *label = [[UILabel alloc] init]; label.text = @"This is label"; label.frame = CGRectMake(0,0,100,100);если из interface builder, то просто поместите метку следующим образом:
yourLabel.frame = CGRectMake(0,0,100,100);
чтобы избавиться от вертикального заполнения для одной строки метки я сделал:
// I have a category method setFrameHeight; you'll likely need to modify the frame. [label setFrameHeight:font.pointSize];или, без категории, используйте:
CGRect frame = label.frame; frame.size.height = font.pointSize; label.frame = frame;
может быть, вы могли бы дать этот код попробовать
CGRect frame = btn.titleLabel.frame; int indent = 20; int inset = 20; [btn.titleLabel setFrame:CGRectMake(frame.origin.x+inset,frame.origin.y,frame.size.width+indent,frame.size.height)];
многие из этих ответов являются сложными. В некоторых случаях, это необходимо. Однако, если Вы читаете это, ваша метка не имеет левого / правого поля, и вы просто хотите немного дополнить, вот все решение:
Шаг 1: добавьте пробелы в конце (буквально, нажмите пробел несколько раз)
Шаг 2: Установите выравнивание текста метки по центру
сделал
если метка создается программно, заполнение может быть вычислено с помощью метода sizeThatFits. При использовании более одной строки текст будет разбит на строки с максимальным значением ширины.
let text = UILabel() let padding = 10 text.layer.cornerRadius = 5 text.layer.masksToBounds = true text.text = "Hello" text.font = UIFont(name: text.font.fontName, size: 18) text.textAlignment = NSTextAlignment.center text.numberOfLines = 1 let maxSize = CGSize(width: 100, height: 100) var size = text.sizeThatFits(maxSize) size.width = size.width + padding * 2 size.height = size.height + padding * 2 text.frame = CGRect(origin: CGPoint(x: 0, y: 0), size: size)

Comments