Je cherche à définir le cadre/marge gauche d'un UILabel
et je ne trouve pas de méthode pour le faire. L'étiquette a un arrière-plan défini, il ne suffit donc pas de modifier son origine. Il serait idéal d’insérer le texte de 10px
ou du côté gauche.
J'ai résolu ce problème en sous-classant UILabel
et en remplaçant drawTextInRect:
comme ceci:
- (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))
}
Swift 4.2.1:
override func drawText(in rect: CGRect) {
let insets = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
super.drawText(in: rect.inset(by: insets))
}
Comme vous l'avez peut-être compris, il s'agit d'une adaptation de réponse de tc. . Il présente deux avantages par rapport à celui-là:
sizeToFit
Pour les textes multilignes, les marges gauche et droite peuvent être définies à l'aide de 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;
La meilleure approche pour ajouter du rembourrage à un UILabel consiste à sous-classer UILabel et à ajouter une propriété edgeInsets. Vous définissez ensuite les incrustations souhaitées et l'étiquette sera dessinée en conséquence.
OSLabel.h
#import <UIKit/UIKit.h>
@interface OSLabel : UILabel
@property (nonatomic, assign) UIEdgeInsets edgeInsets;
@end
OSLabel.m
#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
Le sous-classement est un peu lourd pour un cas aussi simple. Une alternative consiste simplement à ajouter le UILabel sans arrière-plan à un UIView avec l'arrière-plan défini. Définissez le x de l'étiquette sur 10 et agrandissez la taille de la vue extérieure de 20 pixels par rapport à l'étiquette.
J'ai fini par ajouter des espaces au texte:
self.titleLabel.text = [NSString stringWithFormat:@" %@", self.titleLabel.text];
Moche mais efficace, et pas de sous-classe nécessaire.
Vous pouvez aussi essayer "\ t". Pour une solution générique, veuillez vous reporter à la réponse acceptée.
Avec Swift 3, vous pouvez obtenir l'effet souhaité en créant une sous-classe de UILabel
. Dans cette sous-classe, vous devrez ajouter une propriété UIEdgeInsets
avec les encarts requis et la méthode drawText(in:)
, la propriété intrinsicContentSize
(pour le code de mise en page automatique) et/ou la méthode sizeThatFits(_:)
(pour le code Springs & Struts).
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)
}
}
L'exemple suivant montre comment utiliser PaddingLabel
instances dans un 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
}
}
Version rapide de la réponse de Recycled Steel + intrinsizeContentSize()
.
Il prend en charge un style plus traditionnel de définition d'insertions pour d'autres objets de vue avec insertions, tout en permettant de définir des incrustations dans Interface Builder, c'est-à-dire que les incrustations sont définies comme si par programme:
label.inset = UIEdgeInsetsMake(0, 0, 5, 0)
S'il vous plaît laissez-moi savoir s'il y a des bugs.
Swift
@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
}
}
Vous pouvez également résoudre ce problème en initialisant votre UILabel avec un cadre personnalisé.
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];
Nod à astuces CGRect .
Pour les utilisateurs Xamarin (utilisant l'API unifiée):
class UIMarginLabel : UILabel
{
public UIMarginLabel()
{
}
public UIMarginLabel( CGRect frame ) : base( frame )
{
}
public UIEdgeInsets Insets { get; set; }
public override void DrawText( CGRect rect )
{
base.DrawText( Insets.InsetRect( rect ) );
}
}
Et pour ceux qui utilisent l'API MonoTouch d'origine:
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));
}
}
et un @IBDesignable qui le fait fonctionner avec Interface Builder
Swift 4
//
// PaddedLabel.Swift
// TrainCentric
//
// Created by Arsonik
// https://stackoverflow.com/a/33244365/337934
//
import UIKit
@IBDesignable
class PaddedLabel: UILabel {
@IBInspectable var inset:CGSize = CGSize(width: 0, height: 0)
var padding: UIEdgeInsets {
var hasText:Bool = false
if let t = self.text?.count, t > 0 {
hasText = true
}
else if let t = attributedText?.length, 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 drawText(in rect: CGRect) {
super.drawText(in: rect.inset(by: padding))
}
override var 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)
}
}
Swift 2
@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)
}
}
Pour développer la réponse fournie par Brody Robertson, vous pouvez ajouter les bits de conception IB. Cela signifie que vous pouvez ajuster l'étiquette à partir de Storyboard.
Dans votre sous-classe UILabel, faites
#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
Alors fais;
#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
MODIFIER
Vous devriez probablement ajouter une méthode de définition pour edgeInsets.
Si vous ne souhaitez pas utiliser une vue parent supplémentaire pour définir l'arrière-plan, vous pouvez sous-classer UILabel et remplacer textRectForBounds:limitedToNumberOfLines:
. J'ajouterais une propriété textEdgeInsets ou similaire, puis ferais
- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines
{
return [super textRectForBounds:UIEdgeInsetsInsetRect(bounds,textEdgeInsets) limitedToNumberOfLines:numberOfLines];
}
Pour plus de robustesse, vous pouvez également appeler [self setNeedsDisplay] dans setTextEdgeInsets :, mais je ne me dérange généralement pas.
Peut-être plus tard pour la fête, mais ce qui suit fonctionne. Juste la sous-classe 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
Voici une solution Swift. Ajoutez simplement cette classe personnalisée au bas de votre fichier (ou créez-en un nouveau) et utilisez MyLabel au lieu de UILabel lors de la création de votre étiquette.
class MyLabel: UILabel{
override func drawTextInRect(rect: CGRect) {
super.drawTextInRect(UIEdgeInsetsInsetRect(rect, UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 0)))
}
}
Si vous utilisez l'autolayout dans iOS 6+, vous pouvez le faire en ajustant le intrinsicContentSize
dans une sous-classe de 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);
}
En Swift cela résout comme ceci.
class Label: UILabel {
override func drawTextInRect(rect: CGRect) {
super.drawTextInRect(UIEdgeInsetsInsetRect(rect, UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10)))
}
}
Au lieu de UILabel, utilisez peut-être 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 4 version de blyabtroi solution
let leadingMargin: CGFloat = 10
let trailingMargin: CGFloat = 10
let style = NSMutableParagraphStyle()
style.alignment = .justified
style.firstLineHeadIndent = leadingMargin
style.headIndent = leadingMargin
style.tailIndent = trailingMargin
label.attributedText = NSAttributedString(string: "Label with margins",
attributes: [NSAttributedStringKey.paragraphStyle: style])
Cela fonctionne correctement avec les étiquettes multilignes:
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)
}
}
}
réponse de blyabtroi convertie en Swift (aucun sous-classement requis)
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
Je n'ai pas trouvé la suggestion d'utiliser UIButton
dans les réponses ci-dessus. Je vais donc essayer de prouver que c'est un bon choix.
Dans ma situation, utiliser UIButton
était la meilleure solution pour les raisons suivantes:
UIView
en tant que conteneur pour UILabel
(c'est-à-dire que je voulais simplifier les calculs mathématiques pour Autolayout dans ma cellule)NSParagraphStyle
(car tailIndent
ne fonctionne pas correctement avec Autolayout - la largeur de UILabel
est plus petite que prévu.)UITextView
(à cause des effets secondaires possibles)UILabel
(moins de code moins de bugs)C'est pourquoi l'utilisation de la contentEdgeInsets
de UIButton
dans mon cas devient le moyen le plus simple d'ajouter des marges de texte.
J'espère que cela aidera quelqu'un.
Beaucoup de réponses manquent le remplacement de sizeThatFits. Avec cette sous-classe, vous pouvez simplement créer l'étiquette, définir le remplissage, puis dire label.SizeToFit () et le tour est joué.
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
}
}
Swift 3 & AutoLayout version compatible:
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
}
}
C'est la solution la plus simple que j'ai trouvée pour cela:
Swift 4
class CustomLabel: UILabel{
override func drawText(in rect: CGRect) {
super.drawText(in: rect.inset(by: UIEdgeInsets.init(top: 10, left: 10, bottom: 10, right: 10)))
}
}
Assurez-vous de définir vos étiquettes sur la classe CustomLabel
dans le code ainsi que dans le storyboard.
#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
sans sous-classe et tout ce jazz .. je l'ai fait de manière dynamique:
[cell.textLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[cell.textLabel constraintTrailingEqualTo:cell.contentView constant:-100];
la partie contrainte est juste une simple enveloppe de sucre de code (nous avons les mêmes méthodes pour ajouter un rembourrage en haut/en bas/à gauche/à droite).
- (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;
}
(note je l'ai fait dans le contexte de
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath;
vous devrez peut-être appeler [self setNeedsLayout];
selon votre contexte.
Xcode 6.1.1 Swift solution utilisant une extension.
Le nom du fichier pourrait être quelque chose comme "UILabel + AddInsetMargin.Swift":
import UIKit
extension UILabel
{
public override func drawRect(rect: CGRect)
{
self.drawTextInRect(UIEdgeInsetsInsetRect(rect, UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)))
}
}
Si label est créé par programme, le remplissage peut être calculé à l'aide de la méthode sizeThatFits. Si vous utilisez plus d'une ligne, le texte sera une ligne brisée à la valeur de largeur maximale.
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)
Je pense que UILabel
class n’a aucune méthode pour définir la marge. Pourquoi ne pas définir la position de Label à l'endroit requis?
Voir le code ci-dessous:
UILabel *label = [[UILabel alloc] init];
label.text = @"This is label";
label.frame = CGRectMake(0,0,100,100);
si vous utilisez le constructeur d'interface, positionnez simplement Label en procédant comme suit:
yourLabel.frame = CGRectMake(0,0,100,100);
Il suffit d’ajouter des espaces à gauche s’il s’agit d’une seule ligne, plus d’une ligne sera remplie à nouveau par 0.
[self.myLabel setText:[NSString stringWithFormat:@" %@", self.myShortString]];
Pour supprimer le remplissage vertical pour une étiquette à une seule ligne, je l’ai fait:
// I have a category method setFrameHeight; you'll likely need to modify the frame.
[label setFrameHeight:font.pointSize];
OU, sans la catégorie, utilisez:
CGRect frame = label.frame;
frame.size.height = font.pointSize;
label.frame = frame;
Peut-être que vous pourriez essayer ce code
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)];
Vous devez calculer la taille UILabel lorsque vous insérez des incrustations. Le nombre de lignes peut être différent en raison de l'alignement du texte et du mode de saut de ligne.
override func drawText(in rect: CGRect) {
let size = self.sizeThatFits(UIEdgeInsetsInsetRect(rect, insets).size);
super.drawText(in: CGRect.init(Origin: CGPoint.init(x: insets.left, y: insets.top), size: size));
}
override var intrinsicContentSize: CGSize {
var size = super.intrinsicContentSize;
if text == nil || text?.count == 0 {
return size;
}
size = self.sizeThatFits(UIEdgeInsetsInsetRect(CGRect.init(Origin: CGPoint.zero, size: size), insets).size);
size.width += self.insets.left + self.insets.right;
size.height += self.insets.top + self.insets.bottom;
return size;
}