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
?
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];
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ż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];
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;
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.
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łaniasizeToFit
wviewDidLoad
Nie będzie działać, ponieważ autolayout rozmiar i pozycjonuje podglądy po wywołaniuviewDidLoad
i natychmiast cofnie efekty wywołaniasizeToFit
. Jednak wywołaniesizeToFit
z wewnątrzviewDidLayoutSubviews
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;
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
-
Ustaw nowy tekst:
myLabel.text = @"Some Text"
-
Ustaw
maximum number
linii na 0 (automatycznie):myLabel.numberOfLines = 0
-
Ustaw ramkę etykiety na maksymalny rozmiar:
myLabel.frame = CGRectMake(20,20,200,800)
-
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.
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.
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.
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)
}
}
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];
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
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.
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
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];
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
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
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];
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
Dostosowywanie ograniczeń UILabel LefMargin, RightMargin i Top Margin.
Zmień
Content Compression Resistance Priority For Vertical
=1000` tak, aby w pionie > w poziomie .
Edited:
noOfLines=0
I następujące ograniczenia są wystarczające, aby osiągnąć pożądane rezultaty.
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 .
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
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 "];
}
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.
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
Możesz użyć TTTAttributedLabel , obsługuje wyrównanie pionowe.
@property (nonatomic) TTTAttributedLabel* label;
<...>
//view's or viewController's init method
_label.verticalAlignment = TTTAttributedLabelVerticalAlignmentTop;
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)
}
}
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
.
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 .
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!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.
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.
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];
}
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.
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
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
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:
- podziel linie samodzielnie (ignorując ustawienia zawijania etykiet)
- 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
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