Turiu UILabel
, kurioje yra vietos dviem teksto eilutėms. Kartais, kai tekstas yra per trumpas, jis rodomas vertikaliame etiketės centre.
Kaip vertikaliai išlyginti tekstą, kad jis visada būtų UILabel
viršuje?
Nėra būdo nustatyti vertikalųjį lygiavimą UILabel
, tačiau tą patį efektą galima pasiekti pakeitus etiketės rėmelį. Savo etiketes paversiu oranžinėmis, kad aiškiai matytumėte, kas vyksta.
Štai greitas ir paprastas būdas, kaip tai padaryti:
[myLabel sizeToFit];
Jei turite etiketę su ilgesniu tekstu, kuris užims daugiau nei vieną eilutę, nustatykite numberOfLines
į 0
(nulis čia reiškia neribotą eilučių skaičių).
myLabel.numberOfLines = 0;
[myLabel sizeToFit];
Pilnesnė versija
Aš'padarysiu savo etiketę kodu, kad galėtumėte pamatyti, kas vyksta. Didžiąją dalį to galite nustatyti ir Interface Builder programoje. Mano sąranka yra View-Based App su fono paveikslėliu, kurį sukūriau Photoshop programoje, kad parodyčiau paraštes (20 taškų). Etiketė yra patrauklios oranžinės spalvos, kad matytumėte, kas vyksta su matmenimis.
- (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];
}
Kai kurie sizeToFit
naudojimo apribojimai atsiranda, kai tekstas lygiuojamas centre arba dešinėje. Štai kas atsitinka:
// myLabel.textAlignment = NSTextAlignmentRight;
myLabel.textAlignment = NSTextAlignmentCenter;
[myLabel setNumberOfLines:0];
[myLabel sizeToFit];
Etiketės dydis vis dar yra fiksuoto dydžio su viršutiniu kairiuoju kampu. Galite išsaugoti originalios etiketės plotį kintamajame ir nustatyti jį po sizeToFit
arba suteikti jai fiksuotą plotį, kad išvengtumėte šių problemų:
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;
Atkreipkite dėmesį, kad sizeToFit
atsižvelgs į jūsų pradinį etiketės'minimalų plotį. Jei pradėsite nuo 100 pločio etiketės ir iškviesite sizeToFit
, jums bus grąžinta (galbūt labai aukšta) 100 (arba šiek tiek mažesnio) pločio etiketė. Prieš keisdami dydį galite nustatyti mažiausią norimą etiketės plotį.
Keletas kitų dalykų, į kuriuos reikia atkreipti dėmesį:
Tai, ar laikomasi lineBreakMode
, priklauso nuo to, kaip jis nustatytas. NSLineBreakByTruncatingTail
(numatytasis) ignoruojamas po sizeToFit
, kaip ir kiti du sutrumpinimo režimai (galvos ir vidurio). NSLineBreakByClipping
taip pat ignoruojamas. NSLineBreakByCharWrapping
veikia kaip įprasta. Rėmelio plotis vis dar siaurinamas, kad tilptų į dešiniausią dešinę raidę.
Mark Amery komentaruose pateikė pataisymą, skirtą NIB ir "Storyboards", naudojant automatinį išdėstymą:
Jei jūsų etiketė yra įtraukta į nib arba storyboard kaip ViewController, kuris naudoja automatinį išdėstymą,
view
subview, tadasizeToFit
iškvietimas įviewDidLoad
neveiks, nes automatinis išdėstymas padidina ir pozicionuoja subview poviewDidLoad
iškvietimo ir iš karto panaikinasizeToFit
iškvietimo poveikį. TačiausizeToFit
iškvietimas išviewDidLayoutSubviews
veiks.
Čia naudojamas NSString
metodas sizeWithFont:constrainedToSize:lineBreakMode:
, kad būtų apskaičiuotas rėmelio aukštis, kurio reikia eilutei sutalpinti, tada nustatoma pradžia ir plotis.
Pakeiskite rėmelio, skirto etiketei, dydį, naudodami tekstą, kurį norite įterpti. Taip galėsite sutalpinti bet kokį eilučių skaičių.
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;
Kaip ir pirmiau pateiktas atsakymas, bet jis nebuvo visiškai teisingas arba jį nebuvo lengva įtraukti į kodą, todėl aš jį šiek tiek patobulinau. Pridėkite šį plėtinį į atskirą .h ir .m failą arba tiesiog įklijuokite tiesiai virš įgyvendinimo, kuriame ketinate jį naudoti:
#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
Tada naudokite, įrašykite savo tekstą į etiketę, o tada iškvieskite atitinkamą metodą, kad jį sulygiuotumėte:
[myLabel alignTop];
arba
[myLabel alignBottom];
Aš paėmė šiek tiek laiko skaityti kodą, taip pat kodą pristatytame puslapyje, ir nustatė, kad jie visi bando pakeisti etiketės rėmo dydį, kad numatytasis centro vertikalus lygiavimas nebūtų rodomas.
Tačiau kai kuriais atvejais norime, kad etiketė užimtų visus tuos tarpus, net jei etiketėje yra tiek teksto (pvz., kelios vienodo aukščio eilutės).
Čia aš panaudojau alternatyvų sprendimo būdą, tiesiog įterpdamas naujas eilutes į etiketės pabaigą (pls atkreipkite dėmesį, kad iš tikrųjų paveldėjau UILabel
, bet tai nėra būtina):
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 "];
}