Jeg har en "UILabel" med plass til to linjer med tekst. Noen ganger, når teksten er for kort, vises denne teksten i den vertikale midten av etiketten.
Hvordan justerer jeg teksten vertikalt slik at den alltid står øverst på "UILabel"?
Bilde som viser en UILabel med vertikalt sentrert tekst]1.
Det er ingen måte å stille inn den vertikale justeringen på en "UILabel", men du kan få samme effekt ved å endre etikettens ramme. Jeg har gjort etikettene mine oransje slik at du kan se tydelig hva som skjer.
Her er den raske og enkle måten å gjøre dette på:
[myLabel sizeToFit];
Hvis du har en etikett med lengre tekst som vil utgjøre mer enn én linje, setter du numberOfLines
til 0
(null betyr her et ubegrenset antall linjer).
myLabel.numberOfLines = 0;
[myLabel sizeToFit];
Lengre etikettekst med sizeToFit]2
Lengere versjon
Jeg lager etiketten min i kode slik at du kan se hva som skjer. Du kan sette opp det meste av dette i Interface Builder også. Oppsettet mitt er en visningsbasert app med et bakgrunnsbilde jeg laget i Photoshop for å vise marginer (20 poeng). Etiketten har en attraktiv oransje farge slik at du kan se hva som skjer med dimensjonene.
- (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];
}
Noen begrensninger ved bruk av sizeToFit
spiller inn med midtstilt eller høyrejustert tekst. Her er hva som skjer:
// myLabel.textAlignment = NSTextAlignmentRight;
myLabel.textAlignment = NSTextAlignmentCenter;
[myLabel setNumberOfLines:0];
[myLabel sizeToFit];
Etiketten er fortsatt dimensjonert med et fast øvre venstre hjørne. Du kan lagre den opprinnelige etikettens bredde i en variabel og angi den etter sizeToFit
, eller gi den en fast bredde for å motvirke disse problemene:
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;
Merk at sizeToFit
vil respektere den opprinnelige etikettens minimumsbredde. Hvis du starter med en etikett som er 100 bred og kaller sizeToFit
på den, vil den gi deg tilbake en (muligens veldig høy) etikett med 100 (eller litt mindre) bredde. Det kan være lurt å sette etiketten til den minste bredden du ønsker før du endrer størrelsen.
Korrekt etikettjustering ved å endre størrelsen på rammebredden]5.
Noen andre ting å merke seg:
Hvorvidt lineBreakMode
respekteres avhenger av hvordan den er satt. NSLineBreakByTruncatingTail(standard) ignoreres etter
sizeToFit, i likhet med de to andre trunkeringsmodusene (head og middle). NSLineBreakByClipping
ignoreres også. NSLineBreakByCharWrapping` fungerer som vanlig. Rammebredden er fortsatt innsnevret for å passe til bokstaven lengst til høyre.
Mark Amery ga en løsning for NIB-er og Storyboards ved hjelp av Auto Layout i kommentarene:
Hvis etiketten din er inkludert i en nib eller storyboard som en undervisning av
view
av en ViewController som bruker autolayout, vil det ikke fungere å settesizeToFit
-kallet ditt iviewDidLoad
, fordi autolayout størrelser og plasserer undervisningene etter atviewDidLoad
er kalt og vil umiddelbart angre effekten avsizeToFit
-kallet ditt. Å kallesizeToFit
fraviewDidLayoutSubviews
vil imidlertid fungere.
Dette bruker NSString
-metoden sizeWithFont:constrainedToSize:lineBreakMode:
for å beregne rammehøyden som trengs for å passe en streng, og angir deretter opprinnelse og bredde.
Endre størrelsen på rammen for etiketten ved hjelp av teksten du vil sette inn. På den måten kan du få plass til et hvilket som helst antall linjer.
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;
Liker svaret ovenfor, men det var ikke helt riktig, eller lett å smelle inn i koden, så jeg ryddet det litt opp. Legg til denne utvidelsen enten til sin egen .h- og .m-fil eller bare lim inn rett over implementeringen du har tenkt å bruke den:
#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
Og for å bruke, legg teksten din i etiketten, og ring deretter den aktuelle metoden for å justere den:
[myLabel alignTop];
eller
[myLabel alignBottom];
Jeg tok en stund å lese koden, så vel som koden på den introduserte siden, og fant ut at de alle prøver å endre rammestørrelsen på etiketten, slik at standard senter vertikal justering ikke vises.
I noen tilfeller ønsker vi imidlertid at etiketten skal oppta alle disse mellomrommene, selv om etiketten har så mye tekst (f.eks. flere rader med lik høyde).
Her brukte jeg en alternativ måte å løse det på, ved ganske enkelt å legge inn nye linjer til slutten av etiketten (vær oppmerksom på at jeg faktisk arvet UILabel
, men det er ikke nødvendig):
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 "];
}