Wyrównaj tekst w pionie do góry w etykiecie UILabel

Mam UILabel ze spacją na dwie linijki tekstu. Czasami, gdy tekst jest zbyt krótki, jest on wyświetlany w pionowym środku etykiety.

Jak wyrównać tekst w pionie, aby zawsze był na górze UILabel?

obraz przedstawiający Etykietę UILabel z tekstem wyśrodkowanym pionowo

Author: nevan king, 2009-06-28

30 answers

Nie można ustawić wyrównania pionowego na UILabel, ale można uzyskać ten sam efekt, zmieniając ramkę etykiety. Moje etykiety są pomarańczowe, więc widać wyraźnie, co się dzieje.

Oto szybki i łatwy sposób, aby to zrobić:

    [myLabel sizeToFit];

sizeToFit do wyciskania etykiety


Jeśli masz etykietę z dłuższym tekstem, która utworzy więcej niż jedną linię, Ustaw numberOfLines na 0 (zero oznacza tutaj nieograniczoną liczbę linii).

    myLabel.numberOfLines = 0;
    [myLabel sizeToFit];

Dłuższy tekst etykiety z sizeToFit


Dłużej Wersja

Zrobię etykietę w kodzie, abyś mógł zobaczyć, co się dzieje. Większość z nich możesz skonfigurować w Kreatorze interfejsów. Moja konfiguracja to aplikacja oparta na widoku z obrazem tła zrobiłem w Photoshopie, aby pokazać marginesy (20 punktów). Etykieta ma atrakcyjny pomarańczowy kolor, dzięki czemu można zobaczyć, co dzieje się z wymiarami.

- (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];
}

Niektóre ograniczenia użycia sizeToFit wchodzą w grę z tekstem wyrównanym do środka lub do prawej strony. Oto co dzieje się:

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

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

Tutaj wpisz opis obrazka

Etykieta jest nadal wielkości z ustalonym lewym górnym rogu. Można zapisać szerokość oryginalnej etykiety w zmiennej i ustawić ją po sizeToFit, lub nadać jej stałą szerokość, aby przeciwdziałać tym problemom:

    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;

wyrównanie etykiet


Zauważ, że sizeToFit będzie respektować minimalną szerokość etykiety początkowej. Jeśli zaczniesz z etykietą o szerokości 100 i wywołasz sizeToFit na niej, otrzymasz (prawdopodobnie bardzo wysoką) etykietę o szerokości 100 (lub trochę mniej). Możesz chcesz ustawić etykietę na żądaną minimalną szerokość przed zmianą rozmiaru.

Poprawne wyrównanie etykiet poprzez zmianę rozmiaru ramki

Kilka innych rzeczy do zapamiętania:

To, czy lineBreakMode jest przestrzegane, zależy od tego, jak zostanie ustawione. NSLineBreakByTruncatingTail (domyślny) jest ignorowany po sizeToFit, podobnie jak dwa pozostałe tryby obcinania (head i middle). NSLineBreakByClipping jest również ignorowany. Działa jak zwykle. Szerokość ramki jest nadal zwężona, aby pasowała do prawej litery.


Mark Amery dał poprawkę dla stalówek i storyboardów za pomocą Układ automatyczny w komentarzach:

Jeśli etykieta jest dołączona do stalówki lub storyboardu jako podgląd podrzędny view kontrolera widoku, który używa autolayout, to umieszczenie wywołania sizeToFit w viewDidLoad Nie będzie działać, ponieważ autolayout rozmiar i pozycjonuje podglądy po wywołaniu viewDidLoad i natychmiast cofnie efekty wywołania sizeToFit. Jednak wywołanie sizeToFit z wewnątrz viewDidLayoutSubviews będzie działać.


Moja oryginalna odpowiedź (dla potomność/Referencja):

Używa metody NSString sizeWithFont:constrainedToSize:lineBreakMode: do obliczenia wysokości ramki potrzebnej do dopasowania łańcucha, a następnie ustawia początek i szerokość.

Zmień rozmiar ramki etykiety, używając tekstu, który chcesz wstawić. W ten sposób można pomieścić dowolną liczbę linii.

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;
 2723
Author: nevan king,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-11 12:39:06
  1. Ustaw nowy tekst:

    myLabel.text = @"Some Text"
    
  2. Ustaw maximum number linii na 0 (automatycznie):

    myLabel.numberOfLines = 0
    
  3. Ustaw ramkę etykiety na maksymalny rozmiar:

    myLabel.frame = CGRectMake(20,20,200,800)
    
  4. Wywołanie sizeToFit, aby zmniejszyć rozmiar ramki, aby zawartość po prostu pasowała:

    [myLabel sizeToFit]
    

Ramka etykiet jest teraz tylko wysoka i wystarczająco szeroka, aby pasowała do Twojego tekstu. Lewy górny róg powinien pozostać niezmieniony. Testowałem to tylko z tekstem wyrównanym do lewego górnego rogu. W przypadku innych wyrównań możesz trzeba później zmodyfikować ramkę.

Również moja etykieta ma włączone zawijanie słów.

 340
Author: Jakob Egger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-11 12:41:01

Odnosi się do rozwiązania rozszerzenia:

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

Należy zastąpić przez

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

Dodatkowe miejsce jest potrzebne w każdym dodanym nowym wierszu, ponieważ iPhone UILabels ' końcowe zwroty karetki wydają się być ignorowane: (

Podobnie, alignBottom powinien być również zaktualizowany za pomocą @" \n@%" w miejsce "\n@%" (dla inicjalizacji cyklu musi być zastąpiony przez "for(int i=0..."też).

Następujące rozszerzenie działa dla mnie:

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

Następnie wywołaj [yourLabel alignTop]; lub [yourLabel alignBottom]; po każdym tekście yourLabel zadanie.

 161
Author: Dmitri Sologoubenko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-29 05:43:59

Na wypadek, gdyby komuś to pomogło, miałem ten sam problem, ale byłem w stanie rozwiązać ten problem po prostu przechodząc z UILabel Na UITextView. Doceniam, że nie jest to dla wszystkich, ponieważ funkcjonalność jest nieco inna.

Jeśli przełączysz się na użycie UITextView, możesz wyłączyć wszystkie właściwości widoku przewijania oraz włączoną interakcję z użytkownikiem... To zmusi go do działania bardziej jak etykieta.

Tutaj wpisz opis obrazka

 152
Author: jowie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-12 14:10:52

No muss, no fuss

@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

Bez musu, bez Objective-c, bez zamieszania, ale szybko 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)
    }

}

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

}
 132
Author: jasongregori,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-11 12:40:24

Jak w powyższej odpowiedzi, ale nie było to do końca słuszne, lub łatwe do wbicia w kod, więc trochę go wyczyściłem. Dodaj to rozszerzenie do własnego .h i .plik m lub po prostu wklej bezpośrednio nad implementacją, której chcesz użyć:

#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

A następnie, aby użyć, Umieść swój tekst na etykiecie, a następnie wywołaj odpowiednią metodę, aby go wyrównać:

[myLabel alignTop];

Lub

[myLabel alignBottom];
 81
Author: BadPirate,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-05 21:13:51

Najprostsze podejście przy użyciu Storyboard:

Umieść etykietę w StackView i ustaw następujące dwa atrybuty StackView w Inspektorze atrybutów:

1- Axis do Horizontal,

2- Alignment do Top

Tutaj wpisz opis obrazka

 75
Author: Baig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-08 07:16:58

Jeszcze szybszym (i brudniejszym) sposobem na osiągnięcie tego jest ustawienie trybu łamania linii UILabel na "klip" i dodanie stałej liczby nowych linii.

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

To rozwiązanie nie będzie działać dla wszystkich - w szczególności, jeśli nadal chcesz pokazać "..."na końcu twojego ciągu, jeśli przekroczy liczbę wyświetlanych linii, będziesz musiał użyć jednego z dłuższych bitów kodu - ale w wielu przypadkach dostaniesz to, czego potrzebujesz.

 71
Author: Purple Ninja Girl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-18 21:08:23

Zamiast UILabel możesz użyć UITextField, który ma opcję wyrównania pionowego:

textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
textField.userInteractionEnabled = NO; // Don't allow interaction
 62
Author: ivanzoid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-10 10:36:41

Zmagałem się z tym przez długi czas i chciałem podzielić się moim rozwiązaniem.

To daje UILabel, który automatycznie połączy tekst w dół do 0,5 skali i wyśrodkuje tekst w pionie. Opcje te są również dostępne w Storyboard / IB.

[labelObject setMinimumScaleFactor:0.5];
[labelObject setBaselineAdjustment:UIBaselineAdjustmentAlignCenters];
 52
Author: David Greco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-08 12:59:05

Utwórz nową klasę

LabelTopAlign

.plik h

#import <UIKit/UIKit.h>


@interface KwLabelTopAlign : UILabel {

}

@end

.m file

#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

Edit

Oto prostsza implementacja, która robi to samo:

#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
 45
Author: sebastian friedrich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-11 23:14:01

Tutaj wpisz opis obrazka

In Interface Builder

  • Ustaw UILabel na rozmiar największego możliwego tekstu
  • Ustaw Lines na "0" w Inspektorze atrybutów

W Twoim kodzie

  • Ustaw tekst etykiety
  • Call sizeToFit on your label

Fragment Kodu:

self.myLabel.text = @"Short Title";
[self.myLabel sizeToFit];
 40
Author: bearMountain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-29 05:45:33

Dla Adaptive UI (iOS8 lub po), wyrównanie pionowe UILabel należy ustawić z StoryBoard zmieniając właściwości noOfLines=0 ' i

Ograniczenia

  1. Dostosowywanie ograniczeń UILabel LefMargin, RightMargin i Top Margin.

  2. Zmień Content Compression Resistance Priority For Vertical=1000` tak, aby w pionie > w poziomie .

Ograniczenia UILabel

Edited:

noOfLines=0

I następujące ograniczenia są wystarczające, aby osiągnąć pożądane rezultaty.

Tutaj wpisz opis obrazka

 37
Author: Rabindra Nath Nandi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-22 22:41:36

Utwórz podklasę UILabel. Działa jak czar:

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

Jak omówiono tutaj .

 35
Author: Martin Wickman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-14 14:33:10

Napisałem funkcję util, aby osiągnąć ten cel. Możesz zajrzeć:

// adjust the height of a multi-line label to make it align vertical with top
+ (void) alignLabelWithTop:(UILabel *)label {
  CGSize maxSize = CGSizeMake(label.frame.size.width, 999);
  label.adjustsFontSizeToFitWidth = NO;

  // get actual height
  CGSize actualSize = [label.text sizeWithFont:label.font constrainedToSize:maxSize lineBreakMode:label.lineBreakMode];
  CGRect rect = label.frame;
  rect.size.height = actualSize.height;
  label.frame = rect;
}

.Jak używać? (Jeśli lblHello jest tworzone przez Interface builder, więc pomijam szczegóły atrybutów UILabel)

lblHello.text = @"Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World!";
lblHello.numberOfLines = 5;
[Utils alignLabelWithTop:lblHello];

Napisałem ją również na moim blogu jako artykuł: http://fstoke.me/blog/?p=2819

 29
Author: firestoke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-23 08:22:23

Trochę czasu zajęło odczytanie kodu, jak również kodu na wprowadzonej stronie i okazało się, że wszyscy próbują zmodyfikować rozmiar ramki etykiety, aby domyślne wyrównanie w pionie nie pojawiało się.

Jednak w niektórych przypadkach chcemy, aby etykieta zajmowała wszystkie te spacje, nawet jeśli etykieta ma tak dużo tekstu (np. wiele wierszy o jednakowej wysokości).

Tutaj użyłem alternatywnego sposobu, aby to rozwiązać, po prostu umieszczając nowe linie na końcu etykiety (pls zauważ, że rzeczywiście odziedziczył UILabel, ale nie jest to konieczne):

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 "];
}
 27
Author: Walty Yeung,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-10 09:30:22

To, co zrobiłem w mojej aplikacji, to ustawienie właściwości linii UILabel na 0, a także utworzenie dolnego ograniczenia etykiety UILabel i upewnienie się, że jest ona ustawiona na > = 0, Jak pokazano na poniższym obrazku. Tutaj wpisz opis obrazka

 24
Author: Jack Tiong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-19 13:36:19

Wziąłem sugestie tutaj i stworzyłem widok, który może owinąć UILabel i będzie go rozmiar i ustawić liczbę linii tak, aby był wyrównany do góry. Po prostu umieść UILabel jako subview:

@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
 20
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-14 01:27:52

Możesz użyć TTTAttributedLabel , obsługuje wyrównanie pionowe.

@property (nonatomic) TTTAttributedLabel* label;
<...>

//view's or viewController's init method
_label.verticalAlignment = TTTAttributedLabelVerticalAlignmentTop;
 20
Author: Andrew Romanov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-18 09:42:51

Użyj textRect(forBounds:limitedToNumberOfLines:).

class TopAlignedLabel: UILabel {
  override func drawText(in rect: CGRect) {
    let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines)
    super.drawText(in: textRect)
  }
}
 17
Author: ma11hew28,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-12-05 16:43:04

Znalazłem odpowiedzi na to pytanie są teraz trochę nieaktualne, więc dodanie tego dla fanów układu auto tam.

Układ Automatyczny sprawia, że ten problem jest dość trywialny. Zakładając, że dodajemy etykietę do UIView *view, następujący kod tego dokona:

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

Wysokość etykiety zostanie obliczona automatycznie (używając znaku intrinsicContentSize), a etykieta zostanie umieszczona od krawędzi do krawędzi poziomo, u góry view.

 16
Author: petehare,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-29 01:21:15

Użyłem wielu powyższych metod i chcę tylko dodać szybkie i brudne podejście, które zastosowałem:

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

Upewnij się, że liczba nowych linii w łańcuchu spowoduje, że dowolny tekst wypełni dostępną przestrzeń pionową i ustaw Etykietę UILabel tak, aby obcinała każdy wypełniony tekst.

Ponieważ czasami wystarczająco dobre jest wystarczająco dobre .

 16
Author: Code Roadie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-30 17:43:21

Chciałem mieć etykietę, która będzie mogła mieć wiele linii, minimalny rozmiar czcionki i wyśrodkować zarówno poziomo, jak i pionowo w widoku nadrzędnym. Dodałem swoją etykietę programowo do mojego widoku:

- (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];
}

I wtedy, gdy chciałem zmienić tekst mojej etykiety...

- (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];
}
Mam nadzieję, że to komuś pomoże!
 14
Author: Johnus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-14 01:14:58

FXLabel (na github) robi to po wyjęciu z pudełka, ustawiając label.contentMode na UIViewContentModeTop. Ten komponent nie jest przeze mnie wykonany, ale jest to komponent, z którego często korzystam i ma mnóstwo funkcji i wydaje się działać dobrze.

 14
Author: jjxtra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-15 21:46:02

Dla każdego, kto czyta ten tekst, ponieważ tekst wewnątrz etykiety nie jest wyśrodkowany pionowo, należy pamiętać, że niektóre typy czcionek nie są jednakowo projektowane. na przykład, jeśli utworzysz etykietę o rozmiarze zapfino 16, zobaczysz, że tekst nie jest idealnie wyśrodkowany w pionie.

Jednak praca z helvetica wyśrodkuje Twój tekst w pionie.

 11
Author: Nir Pengas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-01 00:09:24

Podklasa UILabel i ogranicz rysunek prostokąt, tak:

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

    [super drawTextInRect:rect];
}

Wypróbowałem rozwiązanie polegające na wypełnieniu nowej linii i w niektórych przypadkach napotkałem nieprawidłowe zachowanie. Z mojego doświadczenia wynika, że łatwiej jest ograniczyć rysowanie rect jak wyżej niż bałagan z numberOfLines.

P. S. możesz sobie wyobrazić łatwe wspieranie UIViewContentMode w ten sposób:

- (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
Author: jrc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-03 16:20:09

Jeśli używasz autolayout, ustaw wartość pionową na 1000, w kodzie lub IB. W IB może być konieczne usunięcie ograniczenia wysokości poprzez ustawienie priorytetu na 1, a następnie usunięcie go.

 10
Author: phatmann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-05 16:38:17

Dopóki nie wykonujesz skomplikowanych zadań, możesz używać UITextView zamiast UILabels.

Wyłącz przewijanie.

Jeśli chcesz, aby tekst był wyświetlany całkowicie tylko user sizeToFit i sizeThatFits: metody

 8
Author: thesummersign,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-02 10:50:09

W języku swift,

let myLabel : UILabel!

Aby tekst etykiety pasował do ekranu i był na górze

myLabel.sizeToFit()

Aby czcionka etykiety pasowała do szerokości ekranu lub określonego rozmiaru szerokości.

myLabel.adjustsFontSizeToFitWidth = YES

I jakiś tekst dla etykiety:

myLabel.textAlignment = .center

myLabel.textAlignment = .left

myLabel.textAlignment = .right

myLabel.textAlignment = .Natural

myLabel.textAlignment = .Justified

 8
Author: Dara Tith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-23 02:27:14

Jest to stare rozwiązanie, użyj autolayout na iOS >= 6

Moje rozwiązanie:

  1. podziel linie samodzielnie (ignorując ustawienia zawijania etykiet)
  2. rysuj linie samodzielnie (ignorując wyrównanie etykiet)

@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
 7
Author: Sulthan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-11 12:41:42