एक UILabel के भीतर शीर्ष पर पाठ संरेखित करें


2175

मेरे पास UILabelपाठ की दो पंक्तियों के लिए एक स्थान है। कभी-कभी, जब पाठ बहुत छोटा होता है, तो यह पाठ लेबल के ऊर्ध्वाधर केंद्र में प्रदर्शित होता है।

मैं हमेशा शीर्ष पर स्थित होने के लिए पाठ को कैसे संरेखित करता हूं UILabel?

छवि खड़ी-केंद्रित पाठ के साथ एक UILabel का प्रतिनिधित्व करती है

जवाबों:


2702

वर्टिकल-अलाइन को सेट करने का कोई तरीका नहीं है UILabel, लेकिन आप लेबल के फ्रेम को बदलकर एक ही प्रभाव प्राप्त कर सकते हैं। मैंने अपने लेबल नारंगी कर दिए हैं ताकि आप स्पष्ट रूप से देख सकें कि क्या हो रहा है।

यहाँ यह करने का त्वरित और आसान तरीका है:

    [myLabel sizeToFit];

sizeToFit एक लेबल को निचोड़ने के लिए


यदि आपके पास अधिक लंबे पाठ के साथ एक लेबल है जो एक से अधिक पंक्ति बनाएगा, तो सेट numberOfLinesकिया जाएगा 0(यहां शून्य का मतलब असीमित संख्या में रेखाएं हैं)।

    myLabel.numberOfLines = 0;
    [myLabel sizeToFit];

आकार के साथ लंबा लेबल पाठ


लंबा संस्करण

मैं अपना लेबल कोड में बनाऊंगा ताकि आप देख सकें कि क्या चल रहा है। आप इसे इंटरफ़ेस बिल्डर में भी स्थापित कर सकते हैं। मेरा सेटअप एक दृश्य-आधारित ऐप है जिसकी पृष्ठभूमि छवि मैंने फ़ोटोशॉप में मार्जिन (20 अंक) दिखाने के लिए बनाई है। लेबल एक आकर्षक नारंगी रंग है ताकि आप देख सकें कि आयामों के साथ क्या हो रहा है।

- (void)viewDidLoad
{
    [super viewDidLoad];

    // 20 point top and left margin. Sized to leave 20 pt at right.
    CGRect labelFrame = CGRectMake(20, 20, 280, 150);
    UILabel *myLabel = [[UILabel alloc] initWithFrame:labelFrame];
    [myLabel setBackgroundColor:[UIColor orangeColor]];

    NSString *labelText = @"I am the very model of a modern Major-General, I've information vegetable, animal, and mineral";
    [myLabel setText:labelText];

    // Tell the label to use an unlimited number of lines
    [myLabel setNumberOfLines:0];
    [myLabel sizeToFit];

    [self.view addSubview:myLabel];
}

उपयोग की कुछ सीमाएँ sizeToFitकेंद्र- या सम्‍मिलित पाठ के साथ खेलने में आती हैं। यहाँ क्या होता है:

    // myLabel.textAlignment = NSTextAlignmentRight;
    myLabel.textAlignment = NSTextAlignmentCenter;

    [myLabel setNumberOfLines:0];
    [myLabel sizeToFit];

यहां छवि विवरण दर्ज करें

लेबल अभी भी एक निश्चित शीर्ष-बाएँ कोने से आकार में है। आप एक लेबल में मूल लेबल की चौड़ाई को बचा सकते हैं और इसे सेट कर सकते हैं sizeToFit, या इसे इन समस्याओं का सामना करने के लिए एक निश्चित चौड़ाई दे सकते हैं:

    myLabel.textAlignment = NSTextAlignmentCenter;

    [myLabel setNumberOfLines:0];
    [myLabel sizeToFit];

    CGRect myFrame = myLabel.frame;
    // Resize the frame's width to 280 (320 - margins)
    // width could also be myOriginalLabelFrame.size.width
    myFrame = CGRectMake(myFrame.origin.x, myFrame.origin.y, 280, myFrame.size.height);
    myLabel.frame = myFrame;

लेबल संरेखण


ध्यान दें कि sizeToFitआपके प्रारंभिक लेबल की न्यूनतम चौड़ाई का सम्मान करेंगे। यदि आप 100 चौड़े लेबल से शुरू करते हैं और sizeToFitउस पर कॉल करते हैं, तो यह आपको 100 (या थोड़ी कम) चौड़ाई के साथ एक (संभवतः बहुत लंबा) लेबल वापस देगा। आकार बदलने से पहले आप अपना लेबल न्यूनतम चौड़ाई पर सेट करना चाहते हैं।

फ्रेम चौड़ाई का आकार बदलकर सही लेबल संरेखण

ध्यान देने योग्य कुछ अन्य बातें:

क्या lineBreakModeसम्मान किया जाता है यह इस बात पर निर्भर करता है कि यह कैसे सेट है। NSLineBreakByTruncatingTail(डिफ़ॉल्ट) के बाद नजरअंदाज कर दिया जाता है sizeToFit, जैसा कि अन्य दो ट्रंकेशन मोड (सिर और मध्य) हैं। NSLineBreakByClippingइसकी भी अनदेखी की जाती है। NSLineBreakByCharWrappingहमेशा की तरह काम करता है। फ़्रेम की चौड़ाई को अभी भी सबसे बड़े अक्षर के लिए फिट किया गया है।


मार्क अमेरी ने टिप्पणियों में ऑटो लेआउट का उपयोग करके एनआईबी और स्टोरीबोर्ड के लिए एक फिक्स दिया:

यदि आपका लेबल किसी दृश्य या स्टोरीबोर्ड में viewउप-दृश्य के रूप में शामिल है, जो ऑटोलॉययट का उपयोग करने वाले ViewController का है, तो अपनी sizeToFitकॉल को viewDidLoadकाम में नहीं लाएगा, क्योंकि ऑटोलयूट आकार viewDidLoadकहलाता है और बाद में उप-पोस्ट करता है और आपके प्रभाव को तुरंत समाप्त कर देगा। sizeToFitकहते हैं। हालांकि, sizeToFitभीतर से कॉलिंग काम viewDidLayoutSubviews करेगी


मेरा मूल उत्तर (पश्चात / संदर्भ के लिए):

यह एक स्ट्रिंग को फिट करने के लिए आवश्यक फ्रेम ऊंचाई की गणना करने के लिए NSStringविधि का उपयोग करता है sizeWithFont:constrainedToSize:lineBreakMode:, फिर मूल और चौड़ाई निर्धारित करता है।

उस पाठ का उपयोग करके लेबल के लिए फ़्रेम का आकार बदलें जिसे आप सम्मिलित करना चाहते हैं। इस तरह आप किसी भी संख्या को समायोजित कर सकते हैं।

CGSize maximumSize = CGSizeMake(300, 9999);
NSString *dateString = @"The date today is January 1st, 1999";
UIFont *dateFont = [UIFont fontWithName:@"Helvetica" size:14];
CGSize dateStringSize = [dateString sizeWithFont:dateFont 
        constrainedToSize:maximumSize 
        lineBreakMode:self.dateLabel.lineBreakMode];

CGRect dateFrame = CGRectMake(10, 10, 300, dateStringSize.height);

self.dateLabel.frame = dateFrame;

10
आपको
ऑटोलैयट

4
यहाँ समस्या को हल करने का एक सरल तरीका है: stackoverflow.com/a/26632490/636559
AboulEinein

यदि आप ऑटो लेआउट और स्टोरीबोर्ड का उपयोग करते हैं, तो विकल्प के साथ एक बाधा जोड़ना "बिल्ड टाइम पर निकालें" चेक करने में मदद करेगा
JK ABC

यदि आपको इसके साथ काम करने की आवश्यकता है, adjustsFontSizeToFitWidthतो sizeToFit का उपयोग करें, फिर लेबल के फ्रेम को 0, 0 ,WidthYouWant, label.frame.size.height (जो कि sizeToFit द्वारा निर्धारित नई ऊंचाई है) पर सेट करेंadjustsFontSizeToFitWidth
अल्बर्ट

3
यह उत्तर अनावश्यक रूप से जटिल है और यह "चारों ओर" शब्द का उपयोग कर रहा है। कृपया नीचे दी गई सलाह को केवल ऊर्ध्वाधर सामग्री को बदलने की प्राथमिकता को देखें। किसी भी कोड की आवश्यकता नहीं है ...
बीट्री

335
  1. नया पाठ सेट करें:

    myLabel.text = @"Some Text"
  2. maximum numberलाइनों को 0 पर सेट करें (स्वचालित):

    myLabel.numberOfLines = 0
  3. लेबल का फ्रेम अधिकतम आकार पर सेट करें:

    myLabel.frame = CGRectMake(20,20,200,800)
  4. sizeToFitफ़्रेम का आकार कम करने के लिए कॉल करें ताकि सामग्री बस फिट हो:

    [myLabel sizeToFit]

आपके पाठ को फिट करने के लिए लेबल फ्रेम अब केवल उच्च और चौड़ा है। शीर्ष बाईं ओर अपरिवर्तित होना चाहिए। मैंने इसका परीक्षण केवल शीर्ष बाएँ-संरेखित पाठ के साथ किया है। अन्य संरेखण के लिए, आपको बाद में फ्रेम को संशोधित करना पड़ सकता है।

इसके अलावा, मेरे लेबल में वर्ड रैपिंग सक्षम है।


हे बेन, मैंने बस अपने पुराने कोड को फिर से देखा, और आवश्यक सही कदमों के साथ अपना उत्तर अपडेट किया।
जैकब एगर

इसने मेरे लिए ठीक काम किया। मैंने अपने यूबेलब के आयामों को बदल दिया और संख्याओफ्लिंस को आईबी में 0 में बदल दिया और फिर [myLabel sizeToFit] नामक पाठ को सेट करने के बाद।
डैन एलिस

Attr में लाइनों की संख्या निर्धारित करने के बाद, मेरे लिए पूरी तरह से काम करता है। इंस्पेक्टर
d2burke

1 से अधिक लाइनों की संख्या के मामले में काम नहीं करता है
टॉम

जब आप दो लाइनों का एक लेबल चाहते हैं तो यह काम नहीं करता है, लेकिन पाठ को अधिक लाइनों की आवश्यकता होती है।
जोस मैनुअल अबर्का रॉड्रिग्ज

159

एक्सटेंशन समाधान का संदर्भ लेना:

for(int i=1; i< newLinesToPad; i++) 
    self.text = [self.text stringByAppendingString:@"\n"];

द्वारा प्रतिस्थापित किया जाना चाहिए

for(int i=0; i<newLinesToPad; i++)
    self.text = [self.text stringByAppendingString:@"\n "];

अतिरिक्त स्थान की आवश्यकता प्रत्येक जोड़े गए न्यूलाइन में होती है, क्योंकि iPhone UILabelsके पीछे चलने वाली गाड़ी के रिटर्न को नजरअंदाज किया जाता है :(

इसी तरह, alignBottom भी साथ एक अद्यतन किया जाना चाहिए @" \n@%"के स्थान पर "\n@%"(चक्र प्रारंभ के लिए द्वारा प्रतिस्थापित किया जाना चाहिए भी "के लिए (int i = 0 ...")।

निम्नलिखित एक्सटेंशन मेरे लिए काम करता है:

// -- file: UILabel+VerticalAlign.h
#pragma mark VerticalAlign
@interface UILabel (VerticalAlign)
- (void)alignTop;
- (void)alignBottom;
@end

// -- file: UILabel+VerticalAlign.m
@implementation UILabel (VerticalAlign)
- (void)alignTop {
    CGSize fontSize = [self.text sizeWithFont:self.font];
    double finalHeight = fontSize.height * self.numberOfLines;
    double finalWidth = self.frame.size.width;    //expected width of label
    CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];
    int newLinesToPad = (finalHeight  - theStringSize.height) / fontSize.height;
    for(int i=0; i<newLinesToPad; i++)
        self.text = [self.text stringByAppendingString:@"\n "];
}

- (void)alignBottom {
    CGSize fontSize = [self.text sizeWithFont:self.font];
    double finalHeight = fontSize.height * self.numberOfLines;
    double finalWidth = self.frame.size.width;    //expected width of label
    CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];
    int newLinesToPad = (finalHeight  - theStringSize.height) / fontSize.height;
    for(int i=0; i<newLinesToPad; i++)
        self.text = [NSString stringWithFormat:@" \n%@",self.text];
}
@end

फिर कॉल करें [yourLabel alignTop];या अपने [yourLabel alignBottom];प्रत्येक लैबल पाठ असाइनमेंट के बाद।


@ मैंने देखा कि आप VerticalAlignकोष्ठक के बाद जोड़ रहे हैं @implementation UILabel। उद्देश्य-सी के लिए नया होने के नाते मैं पहले इस सिंटैक्स में नहीं भागा हूं। इसे क्या कहा जाता है?
जूलियन

कमाल है, श्रेणियों के बारे में पता नहीं था, इससे मुझे ऑब्जेक्टिव-सी भाषा के लिए और भी सराहना मिली। अधिक प्रोग्रामर सीखना एक अच्छा प्रोग्रामर बनने के लिए इतना महत्वपूर्ण है।
जीरोइन्जेखॉफ

एक उत्थान दिया। लेकिन iirc यह काम नहीं करेगा यदि आप उन लाइनों की संख्या नहीं जानते हैं जो एक नकारात्मक पहलू है
Tjirp

मुझे पाठ की 3 पंक्तियों को दिखाना है और पाठ को शीर्ष पर संरेखित करना है। इसलिए, क्या मैंने लाइनों की संख्या 3 पर सेट की है। जब मैंने इसे 3 पर सेट किया है, तो मैं "..." देख रहा हूं यदि पाठ कम है (जो एक पंक्ति में फिट बैठता है)। इससे कैसे बचा जाए "..."
सत्यम

1
मैंने इस श्रेणी का एक संपादन पोस्ट किया है, उम्मीद है कि इसे जल्द ही मंजूरी मिल जाएगी। विधियों sizeWithFont:constrainedToSize:lineBreakMode:और आकारविभाजन: दोनों iOS7 में मूल्यह्रास कर रहे हैं। इसके अलावा, यह श्रेणी केवल तभी लेबल पर काम करती है जब
नंबरऑफलाइन

146

बस अगर यह किसी के लिए किसी भी मदद की है, तो मुझे वही समस्या थी लेकिन उपयोग UILabelकरने से उपयोग करने से केवल समस्या को हल करने में सक्षम था UITextView। मैं सराहना करता हूं कि यह सभी के लिए नहीं है क्योंकि कार्यक्षमता थोड़ी भिन्न है।

यदि आप उपयोग करने के लिए स्विच करते हैं UITextView, तो आप सभी स्क्रॉल दृश्य गुणों के साथ-साथ उपयोगकर्ता सहभागिता सक्षम भी बंद कर सकते हैं ... यह एक लेबल की तरह कार्य करने के लिए बाध्य करेगा।

यहां छवि विवरण दर्ज करें


1
यह सुनिश्चित नहीं है कि यह प्रदर्शन को प्रभावित करेगा यदि कई UILabels पाठ विचारों में परिवर्तित हो जाते हैं।
निन्जानेर

2
इस थ्रेड पर अन्य सभी समाधान मेरे लिए iOS 7 (जो भी कारण हो) में काम नहीं किया। लेकिन बस UITextViewमुझे एक वांछित परिणाम का उपयोग कर अभी।
क्लिफ्टन लैब्रम

1
यह एक वर्कअराउंड है, इसे अभी भी प्रामाणिक बनाने के लिए कुछ समायोजन की आवश्यकता है, लेकिन वास्तव में यह सबसे आसान कोई भी कोड समाधान नहीं है जिसे मैंने देखा, अंगूठे।
इटाई स्पेक्टर

1
मुझे यह समाधान पसंद है। दी गई, प्रदर्शन के मुद्दे हो सकते हैं और इस तरह, एक अपेक्षाकृत सरल दृश्य पर एक सरल लेबल के लिए, यह मेरी ज़रूरत के लिए एकदम सही था (और मैं किसी भी प्रदर्शन प्रभाव को नोटिस नहीं कर सकता)
JCutting8

1
इस पद्धति का एक छोटा दोष यह है कि यह पाठ के लिए अतिरिक्त आंतरिक पैडिंग पेश करेगा। एक नकारात्मक बाधा को पेश करने के लिए एक त्वरित सुधार है।
सिरा लैम

122

कोई उपद्रव कोई अव्यवस्था नहीं

@interface MFTopAlignedLabel : UILabel

@end


@implementation MFTopAlignedLabel

- (void)drawTextInRect:(CGRect) rect
{
    NSAttributedString *attributedText = [[NSAttributedString alloc]     initWithString:self.text attributes:@{NSFontAttributeName:self.font}];
    rect.size.height = [attributedText boundingRectWithSize:rect.size
                                            options:NSStringDrawingUsesLineFragmentOrigin
                                            context:nil].size.height;
    if (self.numberOfLines != 0) {
        rect.size.height = MIN(rect.size.height, self.numberOfLines * self.font.lineHeight);
    }
    [super drawTextInRect:rect];
}

@end

कोई उपद्रव, कोई उद्देश्य-ग, कोई उपद्रव नहीं, लेकिन स्विफ्ट 3:

class VerticalTopAlignLabel: UILabel {

    override func drawText(in rect:CGRect) {
        guard let labelText = text else {  return super.drawText(in: rect) }

        let attributedText = NSAttributedString(string: labelText, attributes: [NSFontAttributeName: font])
        var newRect = rect
        newRect.size.height = attributedText.boundingRect(with: rect.size, options: .usesLineFragmentOrigin, context: nil).size.height

        if numberOfLines != 0 {
            newRect.size.height = min(newRect.size.height, CGFloat(numberOfLines) * font.lineHeight)
        }

        super.drawText(in: newRect)
    }

}

स्विफ्ट 4.2

class VerticalTopAlignLabel: UILabel {

    override func drawText(in rect:CGRect) {
        guard let labelText = text else {  return super.drawText(in: rect) }

        let attributedText = NSAttributedString(string: labelText, attributes: [NSAttributedString.Key.font: font])
        var newRect = rect
        newRect.size.height = attributedText.boundingRect(with: rect.size, options: .usesLineFragmentOrigin, context: nil).size.height

        if numberOfLines != 0 {
            newRect.size.height = min(newRect.size.height, CGFloat(numberOfLines) * font.lineHeight)
        }

        super.drawText(in: newRect)
    }

}

स्विफ्ट संस्करण ने मेरे लिए बिना किसी दुष्प्रभाव के काम किया! अच्छा कार्य!
l.vasilev

2
संभवतः यहां सबसे अच्छा उत्तर, सभी परिदृश्यों में काम करता है। sizeToFit काम नहीं करता है अगर लेबल UITableviewCell में है। अच्छा कार्य।
रजत चौहान

79

ऊपर दिए गए उत्तर की तरह, लेकिन यह कोड में थप्पड़ मारने के लिए काफी सही या आसान नहीं था, इसलिए मैंने इसे थोड़ा साफ किया। इस एक्सटेंशन को या तो स्वयं के लिए .h और .m फ़ाइल में जोड़ें या इसे लागू करने के ठीक ऊपर पेस्ट करें जिसे आप इसका उपयोग करना चाहते हैं:

#pragma mark VerticalAlign
@interface UILabel (VerticalAlign)
- (void)alignTop;
- (void)alignBottom;
@end


@implementation UILabel (VerticalAlign)
- (void)alignTop
{
    CGSize fontSize = [self.text sizeWithFont:self.font];

    double finalHeight = fontSize.height * self.numberOfLines;
    double finalWidth = self.frame.size.width;    //expected width of label


    CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];


    int newLinesToPad = (finalHeight  - theStringSize.height) / fontSize.height;

    for(int i=0; i<= newLinesToPad; i++)
    {
        self.text = [self.text stringByAppendingString:@" \n"];
    }
}

- (void)alignBottom
{
    CGSize fontSize = [self.text sizeWithFont:self.font];

    double finalHeight = fontSize.height * self.numberOfLines;
    double finalWidth = self.frame.size.width;    //expected width of label


    CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];


    int newLinesToPad = (finalHeight  - theStringSize.height) / fontSize.height;

    for(int i=0; i< newLinesToPad; i++)
    {
        self.text = [NSString stringWithFormat:@" \n%@",self.text];
    }
}
@end

और फिर उपयोग करने के लिए, अपने पाठ को लेबल में डालें, और फिर उसे संरेखित करने के लिए उपयुक्त विधि को कॉल करें:

[myLabel alignTop];

या

[myLabel alignBottom];

sizeWithFont पदावनत किया गया
tdios

68

इसे पूरा करने का एक और भी तेज़ (और गन्दा) तरीका है यूबिलब के लाइन ब्रेक मोड को "क्लिप" पर सेट करके और एक निश्चित मात्रा में न्यूलाइन्स जोड़ना।

myLabel.lineBreakMode = UILineBreakModeClip;
myLabel.text = [displayString stringByAppendingString:"\n\n\n\n"];

यह समाधान सभी के लिए काम नहीं करेगा - विशेष रूप से, यदि आप अभी भी अपनी स्ट्रिंग के अंत में "..." दिखाना चाहते हैं यदि यह आपके द्वारा दिखाई जा रही लाइनों की संख्या से अधिक है, तो आपको एक का उपयोग करना होगा कोड के लंबे टुकड़े - लेकिन बहुत सारे मामलों के लिए यह आपको वही मिलेगा जो आपको चाहिए।


3
लाइन ब्रेक मोड को 'क्लिप' पर सेट करने से लेबल के ऑटो-साइज़ में गड़बड़ी लगती है। UILineBreakModeWordWrapइसके बजाय उपयोग करें ।
नील्स वैन डेर रेस्ट

और बेहतर स्थान जोड़ें "\ n \ n"
djdance

68

स्टोरीबोर्ड का उपयोग करके सबसे आसान तरीका:

StackView में लेबल एम्बेड करें और विशेषता निरीक्षक में StackView की दो विशेषताओं को सेट करें:

1- Axisकरने के लिए Horizontal,

2- Alignmentकरने के लिएTop

यहां छवि विवरण दर्ज करें


1
बेहतर परिणामों के लिए आप इस StackView> View> UILabel कर सकते हैं, क्योंकि जब आप बस एक StackView के अंदर एक UILabel एम्बेड करते हैं, तो StackView न्यूनतम आकार में UILabel को फिट करने का आकार देता है
डैनियल बेल्ट्रामी

महान विचार UILabelकुछ UIViewउपवर्ग में रखने के लिए (सादा UIViewआमतौर पर पर्याप्त है) और उस लेबल को नीचे की दिशा में बढ़ने दें। धन्यवाद!
विक्टर कुचेरा

1
बहुत बढ़िया! यह भी उल्लेख के लायक है कि आप की जरूरत स्पष्ट बाधाओं पर UILabelऔर StackView अपना काम करते हैं। धन्यवाद!
लुइज़ डायस

संपादक के साथ- अपने लेबल के साथ एंबेड मेनू कमांड, चयनित लेबल बाधाएं आपके लिए Xcode द्वारा साफ़ कर दी जाती हैं, आप तब केवल StackView के लिए बाधाओं को सेट कर सकते हैं। यह दृष्टिकोण 'स्विफ्टयूआई' लेआउट दृष्टिकोण के सबसे करीब है जो मैंने इसे खोजा है।
रॉकेट गार्डन

यह काम क्यों करता है?
उपन्यासकार

60

इसके बजाय UILabelआप उपयोग कर सकते हैं UITextFieldजिसमें ऊर्ध्वाधर संरेखण विकल्प है:

textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
textField.userInteractionEnabled = NO; // Don't allow interaction

7
Caveat: UITextField केवल पाठ की एक पंक्ति की अनुमति देता है।
डेविड जेम्स

2
@DavidJames कमेंट पूरा करने के लिए: UITextView अधिक उपयुक्त होगा
CedricSoubrie

49

मैं लंबे समय से इससे जूझ रहा हूं और मैं अपना समाधान साझा करना चाहता था।

यह आपको एक UILabelपाठ देगा जो पाठ को 0.5 तराजू पर ले जाएगा और पाठ को केंद्र में रखेगा। ये विकल्प स्टोरीबोर्ड / आईबी में भी उपलब्ध हैं।

[labelObject setMinimumScaleFactor:0.5];
[labelObject setBaselineAdjustment:UIBaselineAdjustmentAlignCenters];

यह प्रदान किए गए सभी उत्तरों के बीच एकदम सही काम किया। धन्यवाद @ डेविड ग्रेको इन गुणों के साथ, यदि हम YES में समायोजन समायोजित करता है तो यह है कि पाठ लेबल के फ्रेम को संशोधित किए बिना फ्रेम में फिट होगा।
अशोक

43

एक नया वर्ग बनाएँ

LabelTopAlign

.h फ़ाइल

#import <UIKit/UIKit.h>


@interface KwLabelTopAlign : UILabel {

}

@end

.m फ़ाइल

#import "KwLabelTopAlign.h"


@implementation KwLabelTopAlign

- (void)drawTextInRect:(CGRect)rect {
    int lineHeight = [@"IglL" sizeWithFont:self.font constrainedToSize:CGSizeMake(rect.size.width, 9999.0f)].height;
    if(rect.size.height >= lineHeight) {
        int textHeight = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(rect.size.width, rect.size.height)].height;
        int yMax = textHeight;
        if (self.numberOfLines > 0) {
            yMax = MIN(lineHeight*self.numberOfLines, yMax);    
        }

        [super drawTextInRect:CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, yMax)];
    }
}

@end

संपादित करें

यहाँ एक सरल कार्यान्वयन है जो समान है:

#import "KwLabelTopAlign.h"

@implementation KwLabelTopAlign

- (void)drawTextInRect:(CGRect)rect
{
    CGFloat height = [self.text sizeWithFont:self.font
                            constrainedToSize:rect.size
                                lineBreakMode:self.lineBreakMode].height;
    if (self.numberOfLines != 0) {
        height = MIN(height, self.font.lineHeight * self.numberOfLines);
    }
    rect.size.height = MIN(rect.size.height, height);
    [super drawTextInRect:rect];
}

@end

असली जवाब के लिए +1। विपरीत sizeToFitसमाधान यह वास्तव में बनाता है UILabelडाल किसी भी शीर्ष पर पाठ, भले ही आप गतिशील रूप से एक लंबे समय तक एक या ठीक इसके विपरीत के साथ एक छोटे पाठ की जगह।
SankE 23

38

यहां छवि विवरण दर्ज करें

इंटरफ़ेस बिल्डर में

  • UILabelसबसे बड़े संभव पाठ के आकार पर सेट करें
  • Linesगुण निरीक्षक में '0' पर सेट करें

अपने कोड में

  • लेबल का पाठ सेट करें
  • sizeToFitअपने लेबल पर कॉल करें

सांकेतिक टुकड़ा:

self.myLabel.text = @"Short Title";
[self.myLabel sizeToFit];

महान काम किया है, मेरे मामले को छोड़कर मुझे 2 से लाइनें सेट करने की आवश्यकता है - एक यूआईटेबल को UITableViewCell के अंदर रखना है और 0 पर सेट करना इसे ओवरलैप करना है, लेकिन 2 पर काम करना (सेल में 2 लाइनों के लिए पर्याप्त जगह है)
eselk

34

अनुकूली UI (iOS8 या उसके बाद) के लिए, संपत्तियों को परिवर्तित करके StoryBoard से UILabel का कार्यक्षेत्र संरेखण निर्धारित किया जाना है noOfLines= 0`

प्रतिबन्ध

  1. UILabel LefMargin, RightMargin और शीर्ष मार्जिन बाधाओं का समायोजन।

  2. बदलें Content Compression Resistance Priority For Vertical= 1000` ताकि ऊर्ध्वाधर> क्षैतिज।

उलीबेले की अड़चनें

संपादित:

noOfLines=0

और निम्नलिखित बाधाएं वांछित परिणाम प्राप्त करने के लिए पर्याप्त हैं।

यहां छवि विवरण दर्ज करें


यह कमाल था। क्या आप बता सकते हैं कि वर्टिकल> हॉरिजॉन्टल ने काम क्यों किया? धन्यवाद।
गेब्रियल

33

UILabel का उपवर्ग बनाएँ। एक जादू की तरह काम करता है:

// TopLeftLabel.h

#import <Foundation/Foundation.h>

@interface TopLeftLabel : UILabel 
{
}

@end

// TopLeftLabel.m

#import "TopLeftLabel.h"

@implementation TopLeftLabel

- (id)initWithFrame:(CGRect)frame 
{
    return [super initWithFrame:frame];
}

- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines 
{
    CGRect textRect = [super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines];    
    textRect.origin.y = bounds.origin.y;
    return textRect;
}

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

@end

जैसा कि यहां चर्चा की गई है


27

मैंने इस उद्देश्य को प्राप्त करने के लिए एक उपयोग समारोह लिखा। आप देख सकते हैं:

// इसे शीर्ष के साथ लंबवत संरेखित करने के लिए एक बहु-पंक्ति लेबल की ऊंचाई समायोजित करें
+ (शून्य) alignLabelWithTop: (UILabel *) लेबल {
  CGSize maxSize = CGSizeMake (label.frame.size. उपलब्धता, 999);
  label.adjustsFontSizeToFitWidth = NO;

  // वास्तविक ऊंचाई प्राप्त करें
  CGSize को वास्तविक करें = [label.text sizeWithFont: label.font constrainedToSize: maxSize lineBreakMode: label.lineBreakMode];
  CGRect rect = label.frame;
  rect.size.height = realSize.height;
  लेबल.फ्रेम = आयत;
}

।कैसे इस्तेमाल करे? (यदि इंटरफ़ेस निर्माता द्वारा lblHello बनाया जाता है, तो मैं कुछ UILabel विशेषताओं को छोड़ता हूं)

lblHello.text = @ "हैलो वर्ल्ड! हैलो वर्ल्ड! हैलो वर्ल्ड! हैलो वर्ल्ड! हैलो वर्ल्ड! हैलो वर्ल्ड! हैलो वर्ल्ड!"।
lblHello.numberOfLines = 5;
[यूटिल्स एलाइनलिबेलविथटॉप: लब्लहोल्लो];

मैंने इसे अपने ब्लॉग पर एक लेख के रूप में भी लिखा है: http://fstoke.me/blog/?p=2819


27

मुझे कोड को पढ़ने में थोड़ा समय लगा, साथ ही प्रस्तुत पृष्ठ में कोड, और उन्होंने पाया कि वे सभी लेबल के फ्रेम आकार को संशोधित करने का प्रयास करते हैं, ताकि डिफ़ॉल्ट केंद्र ऊर्ध्वाधर संरेखण प्रकट न हो।

हालाँकि, कुछ मामलों में हम चाहते हैं कि लेबल उन सभी स्थानों पर कब्जा कर ले, भले ही लेबल में इतना पाठ हो (जैसे कि समान ऊँचाई वाली कई पंक्तियाँ)।

यहाँ, मैंने इसे हल करने के लिए एक वैकल्पिक तरीके का उपयोग किया, बस लेबल के अंत में newlines पैड (pls ध्यान दें कि मुझे वास्तव में विरासत में मिला है UILabel, लेकिन यह आवश्यक नहीं है):

CGSize fontSize = [self.text sizeWithFont:self.font];

finalHeight = fontSize.height * self.numberOfLines;
finalWidth = size.width;    //expected width of label

CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];

int newLinesToPad = (finalHeight  - theStringSize.height) / fontSize.height;

for(int i = 0; i < newLinesToPad; i++)
{
    self.text = [self.text stringByAppendingString:@"\n "];
}

22

मैंने अपने ऐप में जो किया वह था यूबेल की लाइन प्रॉपर्टी को 0 पर सेट करने के साथ-साथ यूबेल के नीचे की बाधा बनाने के लिए और सुनिश्चित करें कि इसे सेट किया जा रहा है> = 0 जैसा कि नीचे की छवि में दिखाया गया है। यहां छवि विवरण दर्ज करें


19

मैंने यहां सुझाव लिया और एक ऐसा दृश्य बनाया, जो एक यूबेल को लपेट सकता है और इसे आकार देगा और लाइनों की संख्या निर्धारित करेगा ताकि यह शीर्ष संरेखित हो। बस एक उपले के रूप में एक UILabel रखो:

@interface TopAlignedLabelContainer : UIView
{
}

@end

@implementation TopAlignedLabelContainer

- (void)layoutSubviews
{
    CGRect bounds = self.bounds;

    for (UILabel *label in [self subviews])
    {
        if ([label isKindOfClass:[UILabel class]])
        {
            CGSize fontSize = [label.text sizeWithFont:label.font];

            CGSize textSize = [label.text sizeWithFont:label.font
                                     constrainedToSize:bounds.size
                                         lineBreakMode:label.lineBreakMode];

            label.numberOfLines = textSize.height / fontSize.height;

            label.frame = CGRectMake(0, 0, textSize.width,
                 fontSize.height * label.numberOfLines);
        }
    }
}

@end


16

मैंने पाया है कि इस प्रश्न के उत्तर अब थोड़ा पुराने हैं, इसलिए इसे ऑटो लेआउट के प्रशंसकों के लिए जोड़ दिया गया।

ऑटो लेआउट इस मुद्दे को बहुत तुच्छ बनाता है। मान लें कि हम लेबल को इसमें जोड़ रहे हैं UIView *view, निम्न कोड इसे पूरा करेगा:

UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
[label setText:@"Some text here"];
[label setTranslatesAutoresizingMaskIntoConstraints:NO];
[view addSubview:label];

[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[label]|" options:0 metrics:nil views:@{@"label": label}]];
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[label]" options:0 metrics:nil views:@{@"label": label}]];

लेबल की ऊंचाई स्वचालित रूप से गणना की जाएगी (इसका उपयोग करते हुए intrinsicContentSize) और लेबल को किनारे से किनारे पर क्षैतिज रूप से स्थित किया जाएगा view


15

मैंने ऊपर बहुत सारे तरीकों का उपयोग किया है, और बस एक त्वरित और गंदा दृष्टिकोण जोड़ना चाहता हूं जिसका मैंने उपयोग किया है:

myLabel.text = [NSString stringWithFormat:@"%@\n\n\n\n\n\n\n\n\n",@"My label text string"];

सुनिश्चित करें कि स्ट्रिंग में नई संख्या की संख्या किसी भी पाठ को उपलब्ध ऊर्ध्वाधर स्थान को भरने का कारण बनेगी, और किसी भी अतिप्रवाहित पाठ को रौंदने के लिए यूआईबेल सेट करें।

क्योंकि कभी-कभी अच्छा काफी अच्छा होता है


हालाँकि, iOS उपकरणों की स्क्रीन साइज हाइट्स में उन्हें भिन्नता दी गई है, फिर उलेबेल को बदलने की ऊँचाई (जो कि एक संभावना है) को ध्यान में रखते हुए '\ n' का वेरिएबल नंबर होना चाहिए। इस प्रकार यह विधि विशेष रूप से उपयोगी दीर्घकालिक नहीं है।
रामबेटिनो

नोट: "त्वरित और गंदे" नहीं "सभी समय के लिए सही समाधान।" मैं तो बस कह रहा हूं'।
कोड रोडी

2
@CodeRoadie त्वरित और गंदे ने मेरे लिए चाल चली, मेरे पास असली जवाब के साथ कुछ लेआउट मुद्दे थे। मैं इसे "सही तरीका" कर सकता था, लेकिन मुझे कुछ समय बचाने के लिए धन्यवाद!
सेरेपिन होचर

@dGambit कृपया ध्यान दें: "त्वरित और गंदा "
कोड रोडी

1
जब मैंने गतिशील रूप से विचारों को लोड करने के लिए कुछ सीखा UITextViewहै, तो यह dlopenपाठ इनपुट का समर्थन करने के लिए कॉल कर सकता है । यह यूआई थ्रेड पर प्रमुख अंतराल पैदा कर सकता है, इसलिए यह दृष्टिकोण बहुत अधिक प्रदर्शन करने वाला है!
यानो

14

मैं एक ऐसा लेबल लगाना चाहता था जो बहु-पंक्तियों, एक न्यूनतम फ़ॉन्ट आकार में सक्षम हो, और यह माता-पिता के दृष्टिकोण में क्षैतिज और लंबवत रूप से केंद्रित हो। मैंने अपने लेबल को मेरे विचार से प्रोग्रामेटिक रूप से जोड़ा:

- (void) customInit {
    // Setup label
    self.label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
    self.label.numberOfLines = 0;
    self.label.lineBreakMode = UILineBreakModeWordWrap;
    self.label.textAlignment = UITextAlignmentCenter;

    // Add the label as a subview
    self.autoresizesSubviews = YES;
    [self addSubview:self.label];
}

और फिर जब मैं अपने लेबल का पाठ बदलना चाहता था ...

- (void) updateDisplay:(NSString *)text {
    if (![text isEqualToString:self.label.text]) {
        // Calculate the font size to use (save to label's font)
        CGSize textConstrainedSize = CGSizeMake(self.frame.size.width, INT_MAX);
        self.label.font = [UIFont systemFontOfSize:TICKER_FONT_SIZE];
        CGSize textSize = [text sizeWithFont:self.label.font constrainedToSize:textConstrainedSize];
        while (textSize.height > self.frame.size.height && self.label.font.pointSize > TICKER_MINIMUM_FONT_SIZE) {
            self.label.font = [UIFont systemFontOfSize:self.label.font.pointSize-1];
            textSize = [ticker.blurb sizeWithFont:self.label.font constrainedToSize:textConstrainedSize];
        }
        // In cases where the frame is still too large (when we're exceeding minimum font size),
        // use the views size
        if (textSize.height > self.frame.size.height) {
            textSize = [text sizeWithFont:self.label.font constrainedToSize:self.frame.size];
        }

        // Draw 
        self.label.frame = CGRectMake(0, self.frame.size.height/2 - textSize.height/2, self.frame.size.width, textSize.height);
        self.label.text = text;
    }
    [self setNeedsDisplay];
}

आशा है कि किसी की मदद करता है!


14

FXLabel (github पर) इस बॉक्स से बाहर जाकर सेटिंग label.contentModeकरता है UIViewContentModeTop। यह घटक मेरे द्वारा नहीं बनाया गया है, लेकिन यह एक ऐसा घटक है जिसका मैं अक्सर उपयोग करता हूं और इसमें बहुत सारी विशेषताएं होती हैं, और यह अच्छी तरह से काम करता है।


11

इसे पढ़ने के लिए क्योंकि आपके लेबल के अंदर का पाठ लंबवत केंद्रित नहीं है, ध्यान रखें कि कुछ फ़ॉन्ट प्रकार समान रूप से डिज़ाइन नहीं किए गए हैं। उदाहरण के लिए, यदि आप zapfino आकार 16 के साथ एक लेबल बनाते हैं, तो आप देखेंगे कि पाठ पूरी तरह से लंबवत केंद्रित नहीं है।

हालांकि, हेलवेटिका के साथ काम करना आपके पाठ को लंबवत केन्द्रित करेगा।


कई कस्टम फोंट ऊर्ध्वाधर केंद्र संरेखित नहीं हैं। UILabel या UITextView हमेशा ऊर्ध्वाधर केंद्र संरेखित होते हैं। IOS प्रोग्रामिंग में वर्टिकल अलाइनमेंट के बारे में सोचने की जरूरत नहीं है।
अमित सिंह

11

का उपयोग करें textRect(forBounds:limitedToNumberOfLines:)

class TopAlignedLabel: UILabel {
    override func drawText(in rect: CGRect) {
        let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines)
        super.drawText(in: textRect)
    }
}

आप सर एक भगवान हैं!
डिओगो एंटुन्स

1
इस उत्तर मिलना चाहिए जिस तरह से अधिक upvotes के रूप में यह अब तक का सबसे अच्छा और साफ समाधान कर रहा है!
माइकल ओच्स

10

उपवर्ग यूआईलेबेल और ड्राइंग आयत को इस तरह से कसना:

- (void)drawTextInRect:(CGRect)rect
{
    CGSize sizeThatFits = [self sizeThatFits:rect.size];
    rect.size.height = MIN(rect.size.height, sizeThatFits.height);

    [super drawTextInRect:rect];
}

मैंने न्यूलाइन पैडिंग से जुड़े समाधान की कोशिश की और कुछ मामलों में गलत व्यवहार में भाग गया। मेरे अनुभव में, ड्रॉइंग रेस्ट को गड़बड़ाने की तुलना में ऊपर से कसना आसान है numberOfLines

पुनश्च आप आसानी से इस तरह UIViewContentMode का समर्थन करने की कल्पना कर सकते हैं:

- (void)drawTextInRect:(CGRect)rect
{
    CGSize sizeThatFits = [self sizeThatFits:rect.size];

    if (self.contentMode == UIViewContentModeTop) {
        rect.size.height = MIN(rect.size.height, sizeThatFits.height);
    }
    else if (self.contentMode == UIViewContentModeBottom) {
        rect.origin.y = MAX(0, rect.size.height - sizeThatFits.height);
        rect.size.height = MIN(rect.size.height, sizeThatFits.height);
    }

    [super drawTextInRect:rect];
}

10

यदि आप ऑटोलेयूट का उपयोग कर रहे हैं, तो 1000 या फिर कोड या आईबी में ऊर्ध्वाधर कंटेंटहिंगपायरिटी सेट करें। IB में तब आपको 1 को प्राथमिकता देकर और फिर इसे हटाकर एक ऊँचाई की बाधा को दूर करना पड़ सकता है।


8

जब तक आप कोई जटिल कार्य नहीं कर रहे हैं, आप UITextViewइसके बजाय उपयोग कर सकते हैं UILabels

स्क्रॉल को अक्षम करें।

यदि आप चाहते हैं कि पाठ पूरी तरह से उपयोगकर्ता sizeToFitऔर sizeThatFits:विधियों को प्रदर्शित करे


8

तेजी से,

let myLabel : UILabel!

स्क्रीन पर फिट होने के लिए अपने लेबल के अपने पाठ को बनाने के लिए और यह शीर्ष पर है

myLabel.sizeToFit()

स्क्रीन की चौड़ाई या विशिष्ट चौड़ाई आकार में फिट होने के लिए अपने फ़ॉन्ट के लेबल को बनाने के लिए।

myLabel.adjustsFontSizeToFitWidth = YES

और लेबल के लिए कुछ पाठ्य सामग्री:

myLabel.textAlignment = .center

myLabel.textAlignment = .left

myLabel.textAlignment = .right

myLabel.textAlignment = .Natural

myLabel.textAlignment = .Justified


पुराने सिंटैक्स से सिंटैक्स का केवल एक परिवर्तन [myLabel sizeToFit]। धन्यवाद!
वेल्कून

7

यह एक पुराना समाधान है, iOS> = 6 पर ऑटोलेयूट का उपयोग करें

मेरा समाधान:

  1. स्वयं द्वारा विभाजित लाइनें (लेबल लपेट सेटिंग को अनदेखा)
  2. अपने आप से रेखाएँ खींचना (लेबल संरेखण की अनदेखी करना)

@interface UITopAlignedLabel : UILabel

@end

@implementation UITopAlignedLabel

#pragma mark Instance methods

- (NSArray*)splitTextToLines:(NSUInteger)maxLines {
    float width = self.frame.size.width;

    NSArray* words = [self.text componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    NSMutableArray* lines = [NSMutableArray array];

    NSMutableString* buffer = [NSMutableString string];    
    NSMutableString* currentLine = [NSMutableString string];

    for (NSString* word in words) {
        if ([buffer length] > 0) {
            [buffer appendString:@" "];
        }

        [buffer appendString:word];

        if (maxLines > 0 && [lines count] == maxLines - 1) {
            [currentLine setString:buffer];
            continue;
        }

        float bufferWidth = [buffer sizeWithFont:self.font].width;

        if (bufferWidth < width) {
            [currentLine setString:buffer];
        }
        else {
            [lines addObject:[NSString stringWithString:currentLine]];

            [buffer setString:word];
            [currentLine setString:buffer];
        }
    }

    if ([currentLine length] > 0) {
        [lines addObject:[NSString stringWithString:currentLine]];
    }

    return lines;
}

- (void)drawRect:(CGRect)rect {
    if ([self.text length] == 0) {
        return;
    }

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, self.textColor.CGColor);
    CGContextSetShadowWithColor(context, self.shadowOffset, 0.0f, self.shadowColor.CGColor);

    NSArray* lines = [self splitTextToLines:self.numberOfLines];
    NSUInteger numLines = [lines count];

    CGSize size = self.frame.size;
    CGPoint origin = CGPointMake(0.0f, 0.0f);

    for (NSUInteger i = 0; i < numLines; i++) {
        NSString* line = [lines objectAtIndex:i];

        if (i == numLines - 1) {
            [line drawAtPoint:origin forWidth:size.width withFont:self.font lineBreakMode:UILineBreakModeTailTruncation];            
        }
        else {
            [line drawAtPoint:origin forWidth:size.width withFont:self.font lineBreakMode:UILineBreakModeClip];
        }

        origin.y += self.font.lineHeight;

        if (origin.y >= size.height) {
            return;
        }
    }
}

@end
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.