[Ios] هامش نص UILabel



Answers

بالنسبة للنص متعدد الأسطر ، يمكن تعيين الهامش الأيسر واليمين باستخدام 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;
Question

أنا أتطلع إلى تعيين UILabel / UILabel الأيسر من UILabel ولا يمكن العثور على طريقة للقيام بذلك. تحتوي العلامة على مجموعة خلفية ، لذا لن يؤدي تغيير الأصل إلا إلى القيام بالخدعة. سيكون مثاليًا لإدراج النص بمقدار 10 10px على الجانب الأيسر.




هذه هي أسهل طريقة وجدت. وهي تعمل مثل سحر بالنسبة لي.

UIView *titleSection = [[UIView alloc] initWithFrame:CGRectMake(0, 0, screenWidth, 100)];
[titleSection addSubview:titleSection];

UILabel *label = [[UILabel alloc] initWithFrame:CGRectInset(titleSection.frame, PADDING, 0)];
[titleSection addSubview:label];



ربما يمكنك إعطاء هذا الرمز محاولة

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)];



Xcode 6.1.1 حل سريع باستخدام امتداد.

قد يكون اسم الملف شيئًا مثل "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)))
    }
}



هنا هو حل سريع. ما عليك سوى إضافة هذه الفئة المخصصة في الجزء السفلي من ملفك (أو إنشاء ملف جديد له) واستخدام MyLabel بدلاً من UILabel عند إنشاء تصنيفك.

class MyLabel: UILabel{
    override func drawTextInRect(rect: CGRect) {
        super.drawTextInRect(UIEdgeInsetsInsetRect(rect, UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 0)))
    }
}



إذا كنت تستخدم 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);
}



للتوسع في الإجابة المقدمة من برودي روبرتسون ، يمكنك إضافة بتات IB Designable. هذا يعني أنه يمكنك ضبط الملصق من داخل Storyboard.

في الخاص بك UILabel subclassed القيام به

#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

تصحيح

ربما ينبغي عليك إضافة طريقة تعيين لـ edgeInsets.




subclassing قليلا مرهقة لهذه الحالة البسيطة. البديل هو ببساطة إضافة UILabel مع عدم تعيين الخلفية إلى UIView مع مجموعة الخلفية. عيّن علامة x إلى 10 وجعل حجم العرض الخارجي 10 بكسل أكبر من الملصق.




#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



أعتقد أن طبقة UILabel ليس لديها طريقة لتحديد الهامش. لماذا لا تحدد وضع التسمية في المكان المطلوب؟

انظر أدناه الكود:

UILabel *label = [[UILabel alloc] init];
label.text = @"This is label";
label.frame = CGRectMake(0,0,100,100);

إذا كنت تستخدم أداة إنشاء الواجهة ، فيمكنك فقط وضع التصنيف من خلال اتباع ما يلي:

yourLabel.frame = CGRectMake(0,0,100,100);



إذا كنت لا ترغب في استخدام عرض أصل إضافي لتعيين الخلفية ، يمكنك تصنيف فئة فرعية UILabel وتجاوز textRectForBounds:limitedToNumberOfLines: سأقوم بإضافة خاصية textEdgeInsets أو ما شابه ، ثم القيام بذلك

- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines
{
  return [super textRectForBounds:UIEdgeInsetsInsetRect(bounds,textEdgeInsets) limitedToNumberOfLines:numberOfLines];
}

للحصول على متانة ، قد ترغب أيضًا في الاتصال بـ [self setNeedsDisplay] في setTextEdgeInsets: ، لكنني عادة لا أزعجك.




الإصدار المتوافق مع 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
    }
}



مع Swift 3 ، يمكنك الحصول على التأثير المطلوب عن طريق إنشاء فئة فرعية من UILabel . في هذه الفئة الفرعية ، ستحتاج إلى إضافة خاصية UIEdgeInsets مع UIEdgeInsets المطلوبة وتجاوز drawText(in:) طريقة drawText(in:) ، خاصية intrinsicContentSize (من أجل رمز تخطيط تلقائي) و / أو sizeThatFits(_:) (لرمز 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)
    }

}

يوضح المثال التالي كيفية استخدام مثيلات PaddingLabel في PaddingLabel :

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
    }

}



الكثير من الإجابات تفتقد تجاوز sizeThatFits. باستخدام هذا الفئة الفرعية يمكنك فقط إنشاء التسمية ، وتعيين الحشو ، ثم قول label.SizeToFit () و voila.

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



إصدار سريع من إجابة Steel Recycled + intrinsizeContentSize() .

وهو يدعم نمطًا أكثر تقليدية لتعيين إدخالات لكائنات العرض الأخرى التي تحتوي على أدوات داخلية أثناء قدرتها على تعيين إدخالات في Interface Builder ، بمعنى أنه يتم تعيين الإضافات بطريقة برمجية:

label.inset = UIEdgeInsetsMake(0, 0, 5, 0)

واسمحوا لي أن أعرف ما إذا كان هناك أي أخطاء.

سويفت 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
    }
}

سويفت 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
    }
}



Links