วิธีตั้งค่าการจัดตำแหน่งซ้ายบนสำหรับแอปพลิเคชัน UILabel สำหรับ iOS


99

ฉันได้เพิ่มป้ายกำกับหนึ่งป้ายในไฟล์ปลายปากกาของฉันแล้วจำเป็นต้องมีการจัดแนวซ้ายบนสำหรับฉลากนั้น เนื่องจากฉันกำลังให้ข้อความในรันไทม์จึงไม่แน่ใจว่ามีบรรทัดเท่าไร ดังนั้นหากข้อความมีเพียงบรรทัดเดียวข้อความนั้นจะปรากฏเป็นแนวตั้งตรงกลาง การจัดตำแหน่งนั้นไม่ตรงกับป้ายกำกับของฉันที่อยู่ข้างหน้า

ตัวอย่างเช่น:

ป้อนคำอธิบายภาพที่นี่

ซึ่งดูแปลก ๆ :(

มีวิธีใดบ้างที่ฉันสามารถตั้งค่าข้อความป้ายกำกับให้เหมาะสมกับการจัดตำแหน่งซ้ายบน?



ในกรณีนี้ให้ใช้ลักษณะของข้อ จำกัด ในเค้าโครงอัตโนมัติความสูงและจุดยึดด้านล่าง
KoreanXcodeWorker

คำตอบ:


61

แทนที่จะอธิบายซ้ำฉันจะเชื่อมโยงไปยังคำถาม / คำตอบที่ค่อนข้างกว้างขวางและได้คะแนนสูง:

จัดแนวข้อความในแนวตั้งไปด้านบนภายใน UILabel

คำตอบสั้น ๆ คือไม่ Apple ไม่ได้ทำให้เรื่องนี้ง่าย แต่เป็นไปได้โดยการเปลี่ยนขนาดเฟรม


65

มันค่อนข้างง่ายที่จะทำ สร้างUILabelsublcass ที่มีverticalAlignmentคุณสมบัติและแทนที่textRectForBounds:limitedToNumberOfLinesเพื่อส่งคืนขอบเขตที่ถูกต้องสำหรับการจัดแนวแนวตั้งด้านบนกลางหรือล่าง นี่คือรหัส:

SOLabel.h

#import <UIKit/UIKit.h>

typedef enum
{
    VerticalAlignmentTop = 0, // default
    VerticalAlignmentMiddle,
    VerticalAlignmentBottom,
} VerticalAlignment;

@interface SOLabel : UILabel

   @property (nonatomic, readwrite) VerticalAlignment verticalAlignment;

@end

SOLabel.m

@implementation SOLabel

-(id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (!self) return nil;

    // set inital value via IVAR so the setter isn't called
    _verticalAlignment = VerticalAlignmentTop;

    return self;
}

-(VerticalAlignment) verticalAlignment
{
    return _verticalAlignment;
}

-(void) setVerticalAlignment:(VerticalAlignment)value
{
    _verticalAlignment = value;
    [self setNeedsDisplay];
}

// align text block according to vertical alignment settings
-(CGRect)textRectForBounds:(CGRect)bounds 
    limitedToNumberOfLines:(NSInteger)numberOfLines
{
   CGRect rect = [super textRectForBounds:bounds 
                   limitedToNumberOfLines:numberOfLines];
    CGRect result;
    switch (_verticalAlignment)
    {
       case VerticalAlignmentTop:
          result = CGRectMake(bounds.origin.x, bounds.origin.y, 
                              rect.size.width, rect.size.height);
           break;

       case VerticalAlignmentMiddle:
          result = CGRectMake(bounds.origin.x, 
                    bounds.origin.y + (bounds.size.height - rect.size.height) / 2,
                    rect.size.width, rect.size.height);
          break;

       case VerticalAlignmentBottom:
          result = CGRectMake(bounds.origin.x, 
                    bounds.origin.y + (bounds.size.height - rect.size.height),
                    rect.size.width, rect.size.height);
          break;

       default:
          result = bounds;
          break;
    }
    return result;
}

-(void)drawTextInRect:(CGRect)rect
{
    CGRect r = [self textRectForBounds:rect 
                limitedToNumberOfLines:self.numberOfLines];
    [super drawTextInRect:r];
}

@end

3
ฉันยังลองวิธีแก้ปัญหาอื่น ๆ อีกมากมายที่นี่ใน SO ก่อนที่จะรันข้ามอันนี้ มันทำงานได้อย่างสมบูรณ์แบบ! โปรดทราบว่าหากคุณทำสิ่งนี้ใน StoryBoard ตรวจสอบให้แน่ใจว่าคุณได้ตั้งค่าแอตทริบิวต์ CustomClass เป็น SOLabel (หรืออะไรก็ตามที่คุณตัดสินใจตั้งชื่อ) แทน UILabel (ใน Utilities Inspector)
TMc

สิ่งนี้มีประโยชน์มากขอบคุณ มันใช้ไม่ได้กับข้อความที่จัดชิดตรงกลางหรือชิดขวา แต่การใช้bounds.size.widthแทนที่จะเป็นrect.size.widthในtextRectForBounds:limitedToNumberOfLines:ดูเหมือนจะแก้ไขได้
Geoff Hackworth

1
หากคุณพบ 'Thread 1: EXC_BAD_ACCESS (Code 2, address = 0x ... )' ใน iOS 9 Xcode 7 เพียงแค่เอา setter ออกและ getter - (VerticalAlignment) verticalAlignment; และ - (โมฆะ) setVerticalAlignment: (VerticalAlignment) ฟังก์ชั่นค่าเนื่องจากตัวแปรคือ @property มันสังเคราะห์และมี accessors
felixwcf

ฉันได้ทำการแก้ไขบางอย่างที่นี่ใน method: "textRectForBounds" - result = CGRectMake (rect.origin.x, bounds.origin.y, rect.size.width, rect.size.height); เพื่อให้งานของฉันเหมาะกับ UILable
g212gs

50

ฉันพบวิธีแก้ปัญหาโดยใช้ AutoLayout ใน StoryBoard

1) ตั้งค่าจำนวนบรรทัดเป็น 0 และการจัดแนวข้อความไปทางซ้าย

ป้อนคำอธิบายภาพที่นี่

2) ตั้งค่าข้อจำกัดความสูง

ป้อนคำอธิบายภาพที่นี่

3) ข้อ จำกัด ความสูงควรอยู่ในความสัมพันธ์ - น้อยกว่าหรือเท่ากับ

ป้อนคำอธิบายภาพที่นี่

4)

   override func viewWillLayoutSubviews() {
        sampleLabel.sizeToFit()
    }

ฉันได้ผลลัพธ์ดังนี้:

ป้อนคำอธิบายภาพที่นี่


2
ใช้งานได้อย่างมีเสน่ห์แม้ใน UITableViewCell ด้วยการใช้ซ้ำ
alex.bour

คุณวางไว้viewWillLayoutSubviewsในคอนโทรลเลอร์หรือไฟล์เซลล์? ถ้าคอนโทรลเลอร์มันจะเข้าถึง UILabel จากเซลล์ได้อย่างไร?
Craig.Pearce

คุณวางขั้นตอนที่ 4 ไว้ที่ไหน? ในฐานะผู้ใช้ใหม่ฉันรู้สึกตื่นเต้นที่จะมีโซลูชัน UI แบบหมดจดจากนั้นรหัสนั้นก็มาจากไหนและเราไม่ได้บอกว่าจะวางไว้
ที่ไหน

ทั้งบน SampleClass.swift หรือ SampleTableViewCell.swift
AG

นี่ควรเป็นทางออก ทำงานได้อย่างสมบูรณ์ไม่จำเป็นต้องแฮ็คหรือคลาสย่อย
Curious101

47

SOLabel ทำงานให้ฉัน

Swift 3 และ 5:

เวอร์ชันนี้ได้รับการอัปเดตจากต้นฉบับเพื่อให้รองรับภาษา RTL:

public class VerticalAlignLabel: UILabel {
    enum VerticalAlignment {
        case top
        case middle
        case bottom
    }

    var verticalAlignment : VerticalAlignment = .top {
        didSet {
            setNeedsDisplay()
        }
    }

    override public func textRect(forBounds bounds: CGRect, limitedToNumberOfLines: Int) -> CGRect {
        let rect = super.textRect(forBounds: bounds, limitedToNumberOfLines: limitedToNumberOfLines)

        if UIView.userInterfaceLayoutDirection(for: .unspecified) == .rightToLeft {
            switch verticalAlignment {
            case .top:
                return CGRect(x: self.bounds.size.width - rect.size.width, y: bounds.origin.y, width: rect.size.width, height: rect.size.height)
            case .middle:
                return CGRect(x: self.bounds.size.width - rect.size.width, y: bounds.origin.y + (bounds.size.height - rect.size.height) / 2, width: rect.size.width, height: rect.size.height)
            case .bottom:
                return CGRect(x: self.bounds.size.width - rect.size.width, y: bounds.origin.y + (bounds.size.height - rect.size.height), width: rect.size.width, height: rect.size.height)
            }
        } else {
            switch verticalAlignment {
            case .top:
                return CGRect(x: bounds.origin.x, y: bounds.origin.y, width: rect.size.width, height: rect.size.height)
            case .middle:
                return CGRect(x: bounds.origin.x, y: bounds.origin.y + (bounds.size.height - rect.size.height) / 2, width: rect.size.width, height: rect.size.height)
            case .bottom:
                return CGRect(x: bounds.origin.x, y: bounds.origin.y + (bounds.size.height - rect.size.height), width: rect.size.width, height: rect.size.height)
            }
        }
    }

    override public func drawText(in rect: CGRect) {
        let r = self.textRect(forBounds: rect, limitedToNumberOfLines: self.numberOfLines)
        super.drawText(in: r)
    }
}

Swift 1:

class UIVerticalAlignLabel: UILabel {

enum VerticalAlignment : Int {
    case VerticalAlignmentTop = 0
    case VerticalAlignmentMiddle = 1
    case VerticalAlignmentBottom = 2
}

var verticalAlignment : VerticalAlignment = .VerticalAlignmentTop {
    didSet {
        setNeedsDisplay()
    }
}

required init(coder aDecoder: NSCoder){
    super.init(coder: aDecoder)
}

override func textRectForBounds(bounds: CGRect, limitedToNumberOfLines: Int) -> CGRect {
    let rect = super.textRectForBounds(bounds, limitedToNumberOfLines: limitedToNumberOfLines)

    switch(verticalAlignment) {
        case .VerticalAlignmentTop:
            return CGRectMake(bounds.origin.x, bounds.origin.y, rect.size.width, rect.size.height)
        case .VerticalAlignmentMiddle:
            return CGRectMake(bounds.origin.x, bounds.origin.y + (bounds.size.height - rect.size.height) / 2, rect.size.width, rect.size.height)
        case .VerticalAlignmentBottom:
            return CGRectMake(bounds.origin.x, bounds.origin.y + (bounds.size.height - rect.size.height), rect.size.width, rect.size.height)
        default:
            return bounds
    }
}

override func drawTextInRect(rect: CGRect) {
    let r = self.textRectForBounds(rect, limitedToNumberOfLines: self.numberOfLines)
    super.drawTextInRect(r)
    }
}

ถ้าฉันพยายามสร้างป้ายกำกับโดยใช้รหัสนี้: var myLabel = VerticalAlignLabel () ฉันได้รับ "ไม่มีอาร์กิวเมนต์สำหรับพารามิเตอร์ 'coder' ในการโทร" ฉันจะสร้างเลเบลโดยใช้คลาสย่อย VerticalAlignLabel นี้ได้อย่างไร
RanLearns

1
ลองใช้ Swift เวอร์ชัน 3 ตอนนี้ - ฉันมีการเริ่มต้นที่จำเป็นซึ่งไม่จำเป็น
totiG

15

ในกรณีของฉันมันเป็นbottom spaceปัญหาข้อ จำกัด = 16ฉันได้ตั้งค่าให้

เมื่อฉันตั้งค่าเป็นbottom to >= 16ปัญหานี้ได้รับการแก้ไขแล้ว

นอกจากนี้หากคุณมีข้อจำกัดความสูงในป้ายกำกับคุณจะต้องลบออก

นี่คือมุมมองข้อ จำกัด ของป้ายกำกับของฉันในตัวตรวจสอบขนาด:

ข้อ จำกัด


ฉันไม่มีตัวเลือกข้อ จำกัด เมื่อฉันเลือกป้ายกำกับ
velkoon

การแก้ไขที่ง่ายที่สุด - ปล่อยให้ข้อ จำกัด และรูปแบบอัตโนมัติดูแลมัน ขอบคุณ!
Jason

13

ในรหัสของคุณ

label.text = @"some text";
[label sizeToFit];

ระวังว่าหากคุณใช้สิ่งนั้นในเซลล์ตารางหรือมุมมองอื่น ๆ ที่นำกลับมาใช้ใหม่ด้วยข้อมูลที่แตกต่างกันคุณจะต้องจัดเก็บเฟรมต้นฉบับไว้ที่ไหนสักแห่งและรีเซ็ตก่อนที่จะเรียกใช้ sizeToFit


ฉันขอแนะนำให้ปล่อยทุกอย่างไว้ที่ Autolayout ณ จุดนี้ สิ่งนี้ไม่จำเป็นอีกต่อไป
13

9

ฉันพบวิธีอื่นสำหรับปัญหาเดียวกัน ฉันใช้UITextViewแทนUILabelและเปลี่ยนeditable()ฟังก์ชันเป็นfalse.


@geekyaleks ทำไมถึงสับแบบโง่ ๆ ดูเหมือนจะเป็นวิธีแก้ปัญหาที่ดีมีปัญหาอื่น ๆ นอกเหนือจากการไม่ตอบคำถามโดยตรงหรือไม่?
Christopher Larsen

ไม่เหมาะสมเนื่องจากคุณไม่ได้ใช้ส่วนประกอบ UI ที่เหมาะสมกับงาน ไม่ควรเป็นการประนีประนอมสำหรับบางสิ่งที่เรียบง่ายเหมือนกับการจัดแนวในแนวตั้ง จำเป็นต้องใช้ส่วนประกอบที่เหมาะสมกับงาน สิ่งอื่นใดคือการแฮ็ก ...
geekyaleks

7

ฉันก็ประสบปัญหานี้เช่นกัน แต่สิ่งที่ฉันพบคือลำดับที่คุณตั้งค่าคุณสมบัติและวิธีการของ UILabel มีความสำคัญ!

หากคุณโทร[label sizeToFit]มาก่อนlabel.font = [UIFont fontWithName:@"Helvetica" size:14];ข้อความจะไม่เรียงชิดด้านบน แต่ถ้าคุณสลับไปมามันก็จะ!

ฉันสังเกตด้วยว่าการตั้งค่าข้อความก่อนก็สร้างความแตกต่างได้เช่นกัน

หวังว่านี่จะช่วยได้


เยี่ยมมาก sizeToFit () ควรถูกเรียกในอันดับสุดท้าย
MKatleast3

4

ในขณะที่คุณใช้ตัวสร้างอินเทอร์เฟซให้กำหนดข้อ จำกัด สำหรับป้ายกำกับของคุณ (อย่าลืมกำหนดความสูงและความกว้างด้วย) จากนั้นในตัวตรวจสอบขนาดให้ตรวจสอบความสูงของป้ายกำกับ ที่นั่นคุณจะต้องการให้อ่าน> = แทน = จากนั้นในการนำไปใช้งานสำหรับ View Controller นั้นให้ตั้งค่าจำนวนบรรทัดเป็น 0 (สามารถทำได้ใน IB) และตั้งค่า label [label sizeToFit]; และเมื่อข้อความของคุณมีความยาวมากขึ้นป้ายกำกับจะมีความสูงและเก็บข้อความของคุณไว้ที่ด้านซ้ายบน


4

หากสิ่งที่คุณต้องการคือข้อความที่ไม่สามารถแก้ไขได้ซึ่งโดยค่าเริ่มต้นจะเริ่มต้นที่มุมบนซ้ายคุณสามารถใช้มุมมองข้อความแทนป้ายกำกับจากนั้นตั้งค่าสถานะเป็นไม่สามารถแก้ไขได้ดังนี้:

textview.isEditable = false

ง่ายกว่ายุ่งกับป้าย ...

ไชโย!


3

วิธีแก้ปัญหาด้วย SoLabel ได้ผลขอบคุณ

ร้องฉันได้เพิ่มเวอร์ชันโมโนทัช:

    public class UICustomLabel : UILabel
{
    private UITextVerticalAlignment _textVerticalAlignment;

    public UICustomLabel()
    {
        TextVerticalAlignment = UITextVerticalAlignment.Top;
    }

    public UITextVerticalAlignment TextVerticalAlignment
    {
        get
        {
            return _textVerticalAlignment;
        }
        set
        {
            _textVerticalAlignment = value;
            SetNeedsDisplay();
        }
    }

    public override void DrawText(RectangleF rect)
    {
        var bound = TextRectForBounds(rect, Lines);
        base.DrawText(bound);
    }

    public override RectangleF TextRectForBounds(RectangleF bounds, int numberOfLines)
    {
        var rect = base.TextRectForBounds(bounds, numberOfLines);
        RectangleF resultRect;
        switch (TextVerticalAlignment)
        {
            case UITextVerticalAlignment.Top:
                resultRect = new RectangleF(bounds.X, bounds.Y, rect.Size.Width, rect.Size.Height);
                break;
            case UITextVerticalAlignment.Middle:
                resultRect = new RectangleF(bounds.X,
                                            bounds.Y + (bounds.Size.Height - rect.Size.Height)/2,
                                            rect.Size.Width, rect.Size.Height);
                break;
            case UITextVerticalAlignment.Bottom:
                resultRect = new RectangleF(bounds.X,
                                            bounds.Y + (bounds.Size.Height - rect.Size.Height),
                                            rect.Size.Width, rect.Size.Height);
                break;

            default:
                resultRect = bounds;
                break;
        }

        return resultRect;
    }
}

public enum UITextVerticalAlignment
{
    Top = 0, // default
    Middle,
    Bottom
}

3

วิธีที่ง่ายที่สุดและง่ายที่สุดคือการป้ายฝังใน StackView และการตั้งค่าแกน StackView เพื่อแนวนอน, ที่สอดคล้องกับสูงสุดในแอตทริบิวต์ตรวจสอบจากสตอรี่บอร์ดเหมือนที่แสดงที่นี่


2

จากคำตอบที่ยอดเยี่ยมของ totiG ฉันได้สร้างคลาส IBDesignable ที่ทำให้ง่ายมากในการปรับแต่งการจัดตำแหน่งแนวตั้งของ UILabel จาก StoryBoard ตรวจสอบให้แน่ใจว่าคุณได้ตั้งค่าคลาสของ UILabel เป็น 'VerticalAlignLabel' จากตัวตรวจสอบข้อมูลประจำตัว StoryBoard หากการจัดแนวแนวตั้งไม่มีผลให้ไปที่ Editor-> Refresh All Views ซึ่งควรทำเคล็ดลับ

วิธีการทำงาน: เมื่อคุณตั้งค่าชั้นเรียนของ UILabel อย่างถูกต้องสตอรี่บอร์ดควรแสดงช่องป้อนข้อมูลที่ใช้จำนวนเต็ม (รหัสการจัดตำแหน่ง)

อัปเดต: ฉันได้เพิ่มการรองรับสำหรับป้ายกำกับกึ่งกลาง~ Sev


ป้อน 0 สำหรับการจัดตำแหน่งสูงสุด

ป้อน 1 สำหรับการจัดตำแหน่งกลาง

ป้อน 2 สำหรับการจัดตำแหน่งด้านล่าง

    @IBDesignable class VerticalAlignLabel: UILabel {
    
    @IBInspectable var alignmentCode: Int = 0 {
        didSet {
            applyAlignmentCode()
        }
    }
    
    func applyAlignmentCode() {
        switch alignmentCode {
        case 0:
            verticalAlignment = .top
        case 1:
            verticalAlignment = .topcenter
        case 2:
            verticalAlignment = .middle
        case 3:
            verticalAlignment = .bottom
        default:
            break
        }
    }
    
    override func awakeFromNib() {
        super.awakeFromNib()
        self.applyAlignmentCode()
    }
    
    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        
        self.applyAlignmentCode()
    }
    
    enum VerticalAlignment {
        case top
        case topcenter
        case middle
        case bottom
    }
    
    var verticalAlignment : VerticalAlignment = .top {
        didSet {
            setNeedsDisplay()
        }
    }
    
    override public func textRect(forBounds bounds: CGRect, limitedToNumberOfLines: Int) -> CGRect {
        let rect = super.textRect(forBounds: bounds, limitedToNumberOfLines: limitedToNumberOfLines)
        
        if #available(iOS 9.0, *) {
            if UIView.userInterfaceLayoutDirection(for: .unspecified) == .rightToLeft {
                switch verticalAlignment {
                case .top:
                    return CGRect(x: self.bounds.size.width - rect.size.width, y: bounds.origin.y, width: rect.size.width, height: rect.size.height)
                case .topcenter:
                    return CGRect(x: self.bounds.size.width - (rect.size.width / 2), y: bounds.origin.y, width: rect.size.width, height: rect.size.height)
                case .middle:
                    return CGRect(x: self.bounds.size.width - rect.size.width, y: bounds.origin.y + (bounds.size.height - rect.size.height) / 2, width: rect.size.width, height: rect.size.height)
                case .bottom:
                    return CGRect(x: self.bounds.size.width - rect.size.width, y: bounds.origin.y + (bounds.size.height - rect.size.height), width: rect.size.width, height: rect.size.height)
                }
            } else {
                switch verticalAlignment {
                case .top:
                    return CGRect(x: bounds.origin.x, y: bounds.origin.y, width: rect.size.width, height: rect.size.height)
                case .topcenter:
                    return CGRect(x: (self.bounds.size.width / 2 ) - (rect.size.width / 2), y: bounds.origin.y, width: rect.size.width, height: rect.size.height)
                case .middle:
                    return CGRect(x: bounds.origin.x, y: bounds.origin.y + (bounds.size.height - rect.size.height) / 2, width: rect.size.width, height: rect.size.height)
                case .bottom:
                    return CGRect(x: bounds.origin.x, y: bounds.origin.y + (bounds.size.height - rect.size.height), width: rect.size.width, height: rect.size.height)
                }
            }
        } else {
            // Fallback on earlier versions
            return rect
        }
    }
    
    override public func drawText(in rect: CGRect) {
        let r = self.textRect(forBounds: rect, limitedToNumberOfLines: self.numberOfLines)
        super.drawText(in: r)
    }
}


2

คุณยังสามารถเปลี่ยน UILabel ของคุณเป็น UITextView ได้เนื่องจากโดยทั่วไปแล้วจะทำสิ่งเดียวกันยกเว้นข้อดีของ UITextView คือข้อความจะถูกจัดแนวโดยอัตโนมัติที่ด้านซ้ายบน


1

ฉันมีปัญหานี้ แต่ป้ายกำกับของฉันอยู่ใน UITableViewCell และในกองทุนวิธีที่ง่ายที่สุดในการแก้ปัญหาคือการสร้าง UIView ที่ว่างเปล่าและตั้งค่าฉลากภายในโดยมีข้อ จำกัด ที่ด้านบนและทางด้านซ้ายเท่านั้นโดยไม่ต้องสาปแช่ง ตั้งค่าจำนวนบรรทัดเป็น 0


0

สำหรับ iOS 7 นั่นคือสิ่งที่ฉันสร้างและทำงานให้ฉัน

@implementation UILabel (VerticalAlign)
- (void)alignTop
{
    CGSize boundingRectSize = CGSizeMake(self.frame.size.width, CGFLOAT_MAX);
    NSDictionary *attributes = @{NSFontAttributeName : self.font};
    CGRect labelSize = [self.text boundingRectWithSize:boundingRectSize options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
                                              attributes:attributes
                                                 context:nil];
    int numberOfLines= ceil(labelSize.size.height / self.font.lineHeight);

    CGRect newFrame = self.frame;
    newFrame.size.height = numberOfLines * self.font.lineHeight;
    self.frame = newFrame;
}

- (void)alignBottom
{
    CGSize boundingRectSize = CGSizeMake(self.frame.size.width, CGFLOAT_MAX);
    NSDictionary *attributes = @{NSFontAttributeName : self.font};
    CGRect labelSize = [self.text boundingRectWithSize:boundingRectSize options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
                                            attributes:attributes
                                               context:nil];
    int numberOfLines= ceil(labelSize.size.height / self.font.lineHeight);

    int numberOfNewLined = (self.frame.size.height/self.font.lineHeight) - numberOfLines;

    NSMutableString *newLines = [NSMutableString string];
    for(int i=0; i< numberOfNewLined; i++){
        [newLines appendString:@"\n"];
    }
    [newLines appendString:self.text];
    self.text = [newLines mutableCopy];
}

0

Swift 2.0 :: การใช้ UILabel Extension

สร้างค่า enum คงที่ในไฟล์ Swift ที่ว่างเปล่า

//  AppRef.swift

import UIKit
import Foundation

enum UILabelTextPositions : String {

 case VERTICAL_ALIGNMENT_TOP = "VerticalAlignmentTop"
 case VERTICAL_ALIGNMENT_MIDDLE = "VerticalAlignmentMiddle"
 case VERTICAL_ALIGNMENT_BOTTOM = "VerticalAlignmentBottom"

}

การใช้ UILabel Extension:

สร้างคลาส Swift ที่ว่างเปล่าและตั้งชื่อ เพิ่มสิ่งต่อไปนี้

//  AppExtensions.swift

import Foundation
import UIKit

    extension UILabel{ 
     func makeLabelTextPosition (sampleLabel :UILabel?, positionIdentifier : String) -> UILabel
     {
      let rect = sampleLabel!.textRectForBounds(bounds, limitedToNumberOfLines: 0)

      switch positionIdentifier
      {
      case "VerticalAlignmentTop":
       sampleLabel!.frame = CGRectMake(bounds.origin.x+5, bounds.origin.y, rect.size.width, rect.size.height)
       break;

      case "VerticalAlignmentMiddle":
       sampleLabel!.frame = CGRectMake(bounds.origin.x+5,bounds.origin.y + (bounds.size.height - rect.size.height) / 2,
        rect.size.width, rect.size.height);
       break;

      case "VerticalAlignmentBottom":
       sampleLabel!.frame = CGRectMake(bounds.origin.x+5, bounds.origin.y + (bounds.size.height - rect.size.height),rect.size.width, rect.size.height);
       break;

      default:
       sampleLabel!.frame = bounds;
       break;
      }
      return sampleLabel!

     }
    }

การใช้งาน:

myMessageLabel.makeLabelTextPosition(messageLabel, positionIdentifier: UILabelTextPositions.VERTICAL_ALIGNMENT_TOP.rawValue)

คุณช่วยอธิบายสิ่งที่จำเป็นสำหรับsampleLabel: UILabel??
Craig.Pearce

ใน func makeLabelTextPosition (sampleLabel: UILabel ?, positionIdentifier: String) {} คุณต้องส่งผ่านวัตถุ UILabel
AG

0

คำตอบของ @ totiG เวอร์ชัน Swift 3

class UIVerticalAlignLabel: UILabel {
    enum VerticalAlignment : Int {
        case VerticalAlignmentTop = 0
        case VerticalAlignmentMiddle = 1
        case VerticalAlignmentBottom = 2
    }

    @IBInspectable var verticalAlignment : VerticalAlignment = .VerticalAlignmentTop {
        didSet {
            setNeedsDisplay()
        }
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func textRect(forBounds bounds: CGRect, limitedToNumberOfLines: Int) -> CGRect {
        let rect = super.textRect(forBounds: bounds, limitedToNumberOfLines: limitedToNumberOfLines)

        switch(verticalAlignment) {
        case .VerticalAlignmentTop:
            return CGRect(x: bounds.origin.x, y: bounds.origin.y, width: rect.size.width, height: rect.size.height)
        case .VerticalAlignmentMiddle:
            return CGRect(x: bounds.origin.x, y: bounds.origin.y + (bounds.size.height - rect.size.height) / 2, width: rect.size.width, height: rect.size.height)
        case .VerticalAlignmentBottom:
            return CGRect(x: bounds.origin.x, y: bounds.origin.y + (bounds.size.height - rect.size.height), width: rect.size.width, height: rect.size.height)
        }
    }

    override func drawText(in rect: CGRect) {
        let r = self.textRect(forBounds: rect, limitedToNumberOfLines: self.numberOfLines)
        super.drawText(in: r)
    }
}

0

คำตอบของ @ totiG ถูกต้องและแก้ไขปัญหาของฉันได้ แต่ฉันพบปัญหาขณะใช้วิธีนี้ในอุปกรณ์ขนาดเล็กเช่น 5s, SE สิ่งนี้ไม่ได้ผลสำหรับฉัน ฉันมีชุดlabel.sizeToFit()ในoverride func layoutSubViews()

override func layoutSubViews() {
    super.layoutSubViews()
    // Do other works if needed
    label.sizeToFit()
}

0

สวิฟต์ 5

เป็นเรื่องง่ายลำดับของคุณสมบัติคือทุกอย่าง

titleLabel.frame = CGRect(x: 20, y: 20, width: 374, height: 291.2)
titleLabel.backgroundColor = UIColor.clear //set a light color to see the frame
titleLabel.textAlignment = .left
titleLabel.lineBreakMode = .byTruncatingTail
titleLabel.numberOfLines = 4
titleLabel.font = UIFont(name: "HelveticaNeue-Bold", size: 35)
titleLabel.text = "Example"
titleLabel.sizeToFit()
self.view.addSubview(titleLabel)

-2

วิธีตั้งค่าการจัดตำแหน่งซ้ายบนสำหรับแอปพลิเคชัน UILabel สำหรับ iOS ป้ายกำกับตั้งค่าโหมดเนื้อหาเป็น "ซ้ายบน" ใช้งานได้สำหรับฉันขอบคุณมาก:
วิธีตั้งค่าการจัดตำแหน่งซ้ายบนสำหรับแอปพลิเคชัน UILabel สำหรับ iOS  ป้ายกำกับตั้งค่าโหมดเนื้อหาเป็น "ซ้ายบน" ใช้งานได้สำหรับฉันขอบคุณมาก


1
ไม่มีอะไรแน่นอนสำหรับฉัน สิ่งนี้ดูเหมือนโดยสังหรณ์ใจว่ามันควรจะเป็นวิธีแก้ปัญหาซึ่งเป็นสาเหตุที่ฉันหันไปหา Google เมื่อมันไม่ได้ผล (หรือดูเหมือนว่าจะทำทุกอย่างสำหรับเรื่องนั้น)
velkoon
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.