ฉันมีUILabel
ช่องว่างสำหรับข้อความสองบรรทัด บางครั้งเมื่อข้อความสั้นเกินไปข้อความนี้จะปรากฏที่กึ่งกลางแนวตั้งของฉลาก
ฉันจะจัดแนวข้อความในแนวตั้งให้อยู่ด้านบนสุดของเสมอได้UILabel
อย่างไร
ฉันมีUILabel
ช่องว่างสำหรับข้อความสองบรรทัด บางครั้งเมื่อข้อความสั้นเกินไปข้อความนี้จะปรากฏที่กึ่งกลางแนวตั้งของฉลาก
ฉันจะจัดแนวข้อความในแนวตั้งให้อยู่ด้านบนสุดของเสมอได้UILabel
อย่างไร
คำตอบ:
ไม่มีวิธีตั้งค่าการจัดแนวตั้งบน a UILabel
แต่คุณสามารถได้รับผลกระทบเดียวกันโดยการเปลี่ยนเฟรมของฉลาก ฉันทำให้ป้ายกำกับเป็นสีส้มเพื่อให้คุณสามารถมองเห็นได้ชัดเจนว่าเกิดอะไรขึ้น
นี่เป็นวิธีที่ง่ายและรวดเร็วในการทำสิ่งนี้:
[myLabel sizeToFit];
หากคุณมีป้ายกำกับที่มีข้อความยาวที่จะสร้างมากกว่าหนึ่งบรรทัดให้ตั้งค่าnumberOfLines
เป็น0
(ศูนย์ที่นี่หมายถึงไม่ จำกัด จำนวนบรรทัด)
myLabel.numberOfLines = 0;
[myLabel sizeToFit];
รุ่นที่ยาวกว่า
ฉันจะทำป้ายกำกับของฉันในรหัสเพื่อให้คุณสามารถเห็นสิ่งที่เกิดขึ้น คุณสามารถตั้งค่าส่วนใหญ่ได้ในเครื่องมือสร้างส่วนต่อประสาน การตั้งค่าของฉันเป็นแอพ View-Based ที่มีภาพพื้นหลังที่ฉันทำใน Photoshop เพื่อแสดงระยะขอบ (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
ทำงานได้ตามปกติ ความกว้างของเฟรมยังคงแคบลงเพื่อให้พอดีกับตัวอักษรที่อยู่ด้านขวาสุด
Mark Ameryให้การแก้ไขสำหรับ NIB และกระดานเรื่องราวโดยใช้เค้าโครงอัตโนมัติในความคิดเห็น:
หากป้ายกำกับของคุณรวมอยู่ในปลายปากกาหรือกระดานเรื่องราวเป็นมุมมองย่อย
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;
adjustsFontSizeToFitWidth
sizeToFit แล้วกำหนดเฟรมของป้ายกำกับเป็น 0, 0, theWidthYouWant, label.frame.size.height (ซึ่งเป็นความสูงใหม่ที่กำหนดโดยขนาด ToFit) จากนั้นadjustsFontSizeToFitWidth
ตั้งค่าข้อความใหม่:
myLabel.text = @"Some Text"
ตั้งค่าmaximum number
ของบรรทัดเป็น 0 (อัตโนมัติ):
myLabel.numberOfLines = 0
กำหนดเฟรมของฉลากเป็นขนาดสูงสุด:
myLabel.frame = CGRectMake(20,20,200,800)
โทรsizeToFit
เพื่อลดขนาดเฟรมเพื่อให้เนื้อหาพอดี:
[myLabel sizeToFit]
เฟรมป้ายผนึกตอนนี้สูงและกว้างพอที่จะใส่ข้อความของคุณ มุมซ้ายบนไม่ควรเปลี่ยนแปลง ฉันทดสอบสิ่งนี้ด้วยข้อความที่ชิดซ้ายบนเท่านั้น สำหรับการจัดแนวอื่นคุณอาจต้องแก้ไขเฟรมหลังจากนั้น
นอกจากนี้ป้ายกำกับของฉันยังเปิดใช้งานการตัดคำด้วย
อ้างอิงถึงโซลูชันส่วนขยาย:
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@%"
(สำหรับการกำหนดค่าเริ่มต้นของรอบจะต้องแทนที่ด้วย "for (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
เป็นสิ่งใหม่สำหรับ Objective-C ฉันไม่ได้พบกับไวยากรณ์นี้มาก่อน สิ่งนี้เรียกว่าอะไร?
sizeWithFont:constrainedToSize:lineBreakMode:
และ sizeWithFont: ทั้งค่าเสื่อมราคาใน iOS7 นอกจากนี้หมวดหมู่นี้ใช้งานได้กับป้ายกำกับเมื่อ numberOfLines มากกว่า 0
ในกรณีที่เป็นความช่วยเหลือกับทุกคนใด ๆ ที่ฉันมีปัญหาเดียวกัน แต่ก็สามารถที่จะช่วยแก้ปัญหาได้ง่ายๆโดยการเปลี่ยนจากการใช้กับการใช้UILabel
UITextView
ฉันชื่นชมสิ่งนี้ไม่ได้มีไว้สำหรับทุกคนเพราะฟังก์ชั่นแตกต่างกันเล็กน้อย
หากคุณสลับไปใช้UITextView
คุณสามารถปิดคุณสมบัติ Scroll View ทั้งหมดรวมถึง User Interaction Enabled ... ซึ่งจะเป็นการบังคับให้ทำหน้าที่เหมือนป้ายกำกับมากขึ้น
UITextView
ผลลัพธ์ที่ต้องการในทันที
ไม่มีความวุ่นวายไม่มีความยุ่งยาก
@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
ไม่มี muss, no Objective-c, ไม่ยุ่งยาก แต่ Swift 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)
}
}
เช่นเดียวกับคำตอบข้างต้น แต่มันไม่ถูกต้องหรือง่ายที่จะตบเป็นรหัสดังนั้นฉันจึงทำความสะอาดมันเล็กน้อย เพิ่มส่วนขยายนี้ลงในไฟล์. 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];
วิธีที่เร็วกว่า (และสกปรกกว่า) ในการทำสิ่งนี้ให้สำเร็จคือการตั้งค่าโหมดการแบ่งบรรทัดของ UILabel เป็น "คลิป" และเพิ่มจำนวนบรรทัดใหม่คงที่
myLabel.lineBreakMode = UILineBreakModeClip;
myLabel.text = [displayString stringByAppendingString:"\n\n\n\n"];
โซลูชันนี้จะไม่ทำงานสำหรับทุกคนโดยเฉพาะถ้าคุณยังต้องการแสดง "... " ที่ท้ายสตริงของคุณหากเกินจำนวนบรรทัดที่คุณแสดงคุณจะต้องใช้หนึ่งใน รหัสที่ยาวขึ้น - แต่สำหรับหลาย ๆ กรณีคุณจะได้รับสิ่งที่คุณต้องการ
UILineBreakModeWordWrap
แทน
วิธีที่ง่ายที่สุดในการใช้ Storyboard:
Embed LabelในStackViewและตั้งค่าสองแอตทริบิวต์ต่อไปนี้ของ StackView ในตัวตรวจสอบแอตทริบิวต์:
1- Axis
ไปHorizontal
,
2- Alignment
ถึงTop
UILabel
ในการวางลงในUIView
คลาสย่อย ( UIView
โดยปกติจะเพียงพอ) และปล่อยให้ฉลากนั้นเติบโตในทิศทางลง ขอบคุณ!
UILabel
และให้ StackView ทำงานของมัน ขอบคุณ!
แทนที่จะเป็นเช่นนั้นUILabel
คุณสามารถใช้UITextField
ซึ่งมีตัวเลือกการจัดแนวตั้ง:
textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
textField.userInteractionEnabled = NO; // Don't allow interaction
ฉันต่อสู้กับอันนี้มานานแล้วและฉันต้องการแบ่งปันวิธีแก้ปัญหาของฉัน
นี่จะให้ข้อความUILabel
ที่จะเชื่อมโยงกับคุณอัตโนมัติถึง 0.5 สเกลและจัดกึ่งกลางข้อความในแนวตั้ง ตัวเลือกเหล่านี้มีอยู่ใน Storyboard / IB
[labelObject setMinimumScaleFactor:0.5];
[labelObject setBaselineAdjustment:UIBaselineAdjustmentAlignCenters];
สร้างคลาสใหม่
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
sizeToFit
การแก้ปัญหานี้จริงทำให้UILabel
ใส่ใด ๆข้อความที่ด้านบนแม้ว่าคุณแบบไดนามิกแทนที่ข้อความสั้นกับอีกหนึ่งหรือในทางกลับกัน
ในเครื่องมือสร้างส่วนต่อประสาน
UILabel
ขนาดของข้อความที่ใหญ่ที่สุดที่เป็นไปได้Lines
เป็น '0' ในตัวตรวจสอบแอททริบิวในรหัสของคุณ
sizeToFit
ป้ายกำกับของคุณตัวอย่างโค้ด:
self.myLabel.text = @"Short Title";
[self.myLabel sizeToFit];
สำหรับ Adaptive UI (iOS8 หรือหลังจากนั้น) การจัดแนวแนวตั้งของ UILabel จะต้องตั้งค่าจากกระดานเรื่องราวด้วยการเปลี่ยนคุณสมบัติ
noOfLines
= 0` และ
ข้อ จำกัด
การปรับ UILabel LefMargin, RightMargin และข้อ จำกัด ด้านบน
เปลี่ยน
Content Compression Resistance Priority For Vertical
= 1,000` ดังนั้นแนวตั้ง> แนวนอน
แก้ไข:
noOfLines=0
และข้อ จำกัด ต่อไปนี้ก็เพียงพอที่จะบรรลุผลลัพธ์ที่ต้องการ
สร้างคลาสย่อยของ 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
ฉันเขียนฟังก์ชัน util เพื่อให้บรรลุวัตถุประสงค์นี้ คุณสามารถดู:
// ปรับความสูงของป้ายกำกับแบบหลายบรรทัดเพื่อให้จัดแนวแนวตั้งกับด้านบน + (เป็นโมฆะ) alignLabelWithTop: (UILabel *) ฉลาก { CGSize maxSize = CGSizeMake (label.frame.size.width, 999); label.adjustsFontSizeToFitWidth = NO; // รับส่วนสูงจริง CGSize actualSize = [label.text sizeWithFont: label.font constrainedToSize: maxSize lineBreakMode: label.lineBreakMode]; CGRect rect = label.frame; rect.size.height = actualSize.height; label.frame = rect; }
.วิธีใช้? (ถ้า lblHello ถูกสร้างขึ้นโดยตัวสร้างส่วนต่อประสานดังนั้นฉันจะข้ามรายละเอียดแอตทริบิวต์ 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];
ฉันยังเขียนมันลงในบล็อกของฉันเป็นบทความ: http://fstoke.me/blog/?p=2819
ฉันใช้เวลาสักครู่เพื่ออ่านโค้ดรวมถึงรหัสในหน้าที่แนะนำและพบว่าพวกเขาทั้งหมดพยายามแก้ไขขนาดเฟรมของฉลากเพื่อให้การจัดแนวแนวตั้งศูนย์เริ่มต้นจะไม่ปรากฏขึ้น
อย่างไรก็ตามในบางกรณีเราต้องการให้ป้ายกำกับใช้ช่องว่างเหล่านั้นทั้งหมดแม้ว่าป้ายกำกับจะมีข้อความมากมาย (เช่นหลายแถวที่มีความสูงเท่ากัน)
ที่นี่ฉันใช้วิธีอื่นในการแก้ปัญหาโดยเพียงแค่ขึ้นบรรทัดใหม่ไปยังจุดสิ้นสุดของป้ายกำกับ (โปรดทราบว่าฉันได้รับมรดกจริง ๆ แล้ว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 "];
}
ฉันทำตามคำแนะนำที่นี่และสร้างมุมมองที่สามารถตัด UILabel และจะปรับขนาดและกำหนดจำนวนบรรทัดเพื่อให้มีการจัดตำแหน่งสูงสุด เพียงใส่ 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
คุณสามารถใช้TTTAttributedLabelซึ่งรองรับการจัดตำแหน่งแนวตั้ง
@property (nonatomic) TTTAttributedLabel* label;
<...>
//view's or viewController's init method
_label.verticalAlignment = TTTAttributedLabelVerticalAlignmentTop;
ฉันพบว่าคำตอบสำหรับคำถามนี้ล้าสมัยไปแล้วดังนั้นการเพิ่มสิ่งนี้สำหรับแฟน ๆ เลย์เอาต์อัตโนมัติที่นั่น
เลย์เอาต์อัตโนมัติทำให้ปัญหานี้เล็กน้อย สมมติว่าเรากำลังเพิ่มป้ายกำกับให้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
Edge-to-ขอบแนวนอนที่ด้านบนของ
ฉันใช้วิธีการด้านบนมากมายและต้องการเพิ่มวิธีที่รวดเร็วและสกปรกที่ฉันใช้:
myLabel.text = [NSString stringWithFormat:@"%@\n\n\n\n\n\n\n\n\n",@"My label text string"];
ตรวจสอบให้แน่ใจว่าจำนวนบรรทัดใหม่ในสตริงจะทำให้ข้อความใด ๆ เติมเต็มช่องว่างในแนวดิ่งที่มีอยู่และตั้งค่า UILabel ให้ตัดทอนข้อความที่ล้นออกมา
เพราะบางครั้งพอที่ดีคือดีพอ
UITextView
คือมันสามารถโทรdlopen
เพื่อรองรับการป้อนข้อความ สิ่งนี้อาจทำให้เกิดความล่าช้าที่สำคัญในเธรด UI ดังนั้นวิธีนี้จึงมีประสิทธิภาพมากกว่า!
ฉันต้องการมีป้ายกำกับที่สามารถมีหลายบรรทัดขนาดตัวอักษรขั้นต่ำและจัดกึ่งกลางทั้งแนวนอนและแนวตั้งในมุมมองหลัก ฉันเพิ่มป้ายกำกับของฉันโดยทางโปรแกรมในมุมมองของฉัน:
- (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];
}
หวังว่าจะช่วยใครบางคน!
FXLabel (บน GitHub)ไม่ออกจากกล่องนี้โดยการตั้งค่าไปlabel.contentMode
UIViewContentModeTop
ฉันไม่ได้ทำส่วนประกอบนี้ แต่เป็นส่วนประกอบที่ฉันใช้บ่อยและมีคุณสมบัติมากมายและดูเหมือนว่าจะทำงานได้ดี
สำหรับทุกคนที่อ่านข้อความนี้เนื่องจากข้อความในป้ายกำกับของคุณไม่ได้อยู่กึ่งกลางแนวตั้งโปรดทราบว่าแบบอักษรบางประเภทไม่ได้รับการออกแบบอย่างเท่าเทียมกัน ตัวอย่างเช่นถ้าคุณสร้างป้ายกำกับที่มี zapfino ขนาด 16 คุณจะเห็นข้อความไม่อยู่กึ่งกลางในแนวตั้งอย่างสมบูรณ์
อย่างไรก็ตามการทำงานกับ helvetica จะทำให้ข้อความของคุณอยู่ตรงกลาง
textRect(forBounds:limitedToNumberOfLines:)
ใช้
class TopAlignedLabel: UILabel {
override func drawText(in rect: CGRect) {
let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines)
super.drawText(in: textRect)
}
}
คลาสย่อย UILabel และ จำกัด ขอบเขตการวาดเช่นนี้:
- (void)drawTextInRect:(CGRect)rect
{
CGSize sizeThatFits = [self sizeThatFits:rect.size];
rect.size.height = MIN(rect.size.height, sizeThatFits.height);
[super drawTextInRect:rect];
}
ฉันลองวิธีแก้ปัญหาที่เกี่ยวข้องกับการขึ้นบรรทัดใหม่และพบพฤติกรรมที่ไม่ถูกต้องในบางกรณี จากประสบการณ์ของผมมันเป็นเรื่องง่ายที่จะ จำกัด การ RECT numberOfLines
ในการวาดภาพดังกล่าวกว่ายุ่งกับ
PS คุณสามารถจินตนาการได้อย่างง่ายดายสนับสนุน 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];
}
หากคุณกำลังใช้การชำระอัตโนมัติให้ตั้งค่าเนื้อหาแนวดิ่งการใส่ลำดับความสำคัญเป็น 1,000 ไม่ว่าจะเป็นรหัสหรือ IB ใน IB คุณอาจต้องลบข้อจำกัดความสูงโดยการตั้งค่าความสำคัญเป็น 1 แล้วลบออก
ตราบใดที่คุณไม่ได้ทำงานที่ซับซ้อนคุณสามารถใช้UITextView
แทนUILabels
แทน
ปิดใช้งานการเลื่อน
หากคุณต้องการให้ข้อความปรากฏอย่างสมบูรณ์เพียงแค่ผู้ใช้sizeToFit
และsizeThatFits:
วิธีการ
อย่างรวดเร็ว
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]
เพียงแค่มีการเปลี่ยนแปลงของไวยากรณ์จากไวยากรณ์เก่า ขอบคุณ!
นี่เป็นวิธีแก้ไขปัญหาเก่าใช้การชำระอัตโนมัติใน iOS> = 6
ทางออกของฉัน:
@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