Jawaban:
Tidak ada cara untuk mengatur vertikal-align pada UILabel
, tetapi Anda bisa mendapatkan efek yang sama dengan mengubah bingkai label. Saya telah membuat label saya berwarna oranye sehingga Anda dapat melihat dengan jelas apa yang terjadi.
Inilah cara cepat dan mudah untuk melakukan ini:
[myLabel sizeToFit];
Jika Anda memiliki label dengan teks yang lebih panjang yang akan menghasilkan lebih dari satu baris, setel numberOfLines
ke 0
(nol di sini berarti jumlah baris yang tidak terbatas).
myLabel.numberOfLines = 0;
[myLabel sizeToFit];
Versi yang lebih panjang
Saya akan membuat label saya dalam kode sehingga Anda dapat melihat apa yang terjadi. Anda dapat mengatur sebagian besar ini di Interface Builder juga. Setup saya adalah Aplikasi Berbasis Tampilan dengan gambar latar belakang yang saya buat di Photoshop untuk menunjukkan margin (20 poin). Labelnya adalah warna oranye yang menarik sehingga Anda dapat melihat apa yang terjadi dengan dimensi.
- (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];
}
Beberapa batasan penggunaan sizeToFit
ikut bermain dengan teks rata tengah atau kanan. Inilah yang terjadi:
// myLabel.textAlignment = NSTextAlignmentRight;
myLabel.textAlignment = NSTextAlignmentCenter;
[myLabel setNumberOfLines:0];
[myLabel sizeToFit];
Label masih berukuran dengan sudut kiri atas yang diperbaiki. Anda dapat menyimpan lebar label asli dalam variabel dan mengaturnya setelahnya sizeToFit
, atau memberinya lebar tetap untuk mengatasi masalah ini:
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;
Perhatikan bahwa sizeToFit
akan menghormati lebar minimum label awal Anda. Jika Anda mulai dengan label 100 lebar dan memanggilnya sizeToFit
, itu akan memberi Anda kembali label (mungkin sangat tinggi) dengan 100 (atau sedikit kurang) lebar. Anda mungkin ingin mengatur label ke lebar minimum yang Anda inginkan sebelum mengubah ukuran.
Beberapa hal lain yang perlu diperhatikan:
Apakah lineBreakMode
dihormati tergantung pada bagaimana pengaturannya. NSLineBreakByTruncatingTail
(default) diabaikan setelahnya sizeToFit
, seperti halnya dua mode pemotongan lainnya (kepala dan tengah). NSLineBreakByClipping
juga diabaikan. NSLineBreakByCharWrapping
bekerja seperti biasa. Lebar bingkai masih menyempit agar pas dengan huruf paling kanan.
Mark Amery memberikan perbaikan untuk NIB dan Storyboard menggunakan Tata Letak Otomatis di komentar:
Jika label Anda termasuk dalam nib atau storyboard sebagai subview dari
view
ViewController yang menggunakan autolayout, maka memasukkansizeToFit
panggilan Anda ke dalamviewDidLoad
tidak akan berhasil, karena ukuran autolayout dan posisi subview setelahviewDidLoad
dipanggil dan akan segera membatalkan efek dari AndasizeToFit
panggilan. Namun, panggilansizeToFit
dari dalamviewDidLayoutSubviews
akan berhasil.
Ini menggunakan NSString
metode sizeWithFont:constrainedToSize:lineBreakMode:
untuk menghitung tinggi bingkai yang dibutuhkan agar pas dengan string, kemudian menetapkan asal dan lebar.
Ubah ukuran bingkai untuk label menggunakan teks yang ingin Anda masukkan. Dengan begitu Anda dapat mengakomodasi sejumlah garis.
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
kemudian gunakan sizeToFit kemudian atur bingkai label ke 0, 0, theWidthYouWant, label.frame.size.height (yang merupakan ketinggian baru ditentukan oleh sizeToFit) MAKA berlakuadjustsFontSizeToFitWidth
Setel teks baru:
myLabel.text = @"Some Text"
Setel maximum number
baris ke 0 (otomatis):
myLabel.numberOfLines = 0
Setel bingkai label ke ukuran maksimum:
myLabel.frame = CGRectMake(20,20,200,800)
Panggilan sizeToFit
untuk mengurangi ukuran bingkai sehingga isinya pas:
[myLabel sizeToFit]
Bingkai label sekarang cukup tinggi dan cukup lebar untuk disesuaikan dengan teks Anda. Kiri atas harus tidak berubah. Saya telah menguji ini hanya dengan teks rata kiri atas. Untuk penyejajaran lainnya, Anda mungkin harus memodifikasi frame sesudahnya.
Juga, label saya memiliki pembungkusan kata diaktifkan.
Mengacu pada solusi ekstensi:
for(int i=1; i< newLinesToPad; i++)
self.text = [self.text stringByAppendingString:@"\n"];
harus diganti oleh
for(int i=0; i<newLinesToPad; i++)
self.text = [self.text stringByAppendingString:@"\n "];
Diperlukan ruang tambahan di setiap baris baru yang ditambahkan, karena UILabels
pengembalinya trailing iPhone tampaknya diabaikan :(
Demikian pula, alignBottom juga harus diperbarui dengan @" \n@%"
di tempat "\n@%"
(untuk inisialisasi siklus harus diganti dengan "untuk (int i = 0 ..." juga).
Ekstensi berikut ini berfungsi untuk saya:
// -- 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
Kemudian panggil [yourLabel alignTop];
atau [yourLabel alignBottom];
setelah setiap tugas teks Label Anda.
VerticalAlign
antara kurung setelah @implementation UILabel
. Menjadi orang baru di Objective-C saya belum pernah menjalankan sintaks ini sebelumnya. Apa ini namanya?
sizeWithFont:constrainedToSize:lineBreakMode:
dan sizeWithFont: keduanya disusutkan di iOS7. Juga, kategori ini hanya berfungsi pada label ketika numberOfLines lebih besar dari 0.
Kalau-kalau ada bantuan untuk siapa pun, saya memiliki masalah yang sama tetapi mampu memecahkan masalah hanya dengan beralih dari menggunakan UILabel
ke menggunakan UITextView
. Saya menghargai ini bukan untuk semua orang karena fungsinya sedikit berbeda.
Jika Anda beralih menggunakan UITextView
, Anda dapat mematikan semua properti Scroll View dan Interaksi Pengguna Diaktifkan ... Ini akan memaksa itu untuk bertindak lebih seperti label.
UITextView
memberi saya hasil yang diinginkan segera.
Tanpa muss, tidak repot
@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
Tidak ada muss, tidak ada Objective-c, tidak ada keributan selain 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)
}
}
Cepat 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)
}
}
Seperti jawaban di atas, tetapi itu tidak benar, atau mudah untuk menampar ke dalam kode jadi saya membersihkannya sedikit. Tambahkan ekstensi ini ke file .h dan .m atau tempelkan tepat di atas implementasi yang ingin Anda gunakan:
#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
Dan kemudian untuk menggunakan, masukkan teks Anda ke label, dan kemudian panggil metode yang sesuai untuk menyelaraskannya:
[myLabel alignTop];
atau
[myLabel alignBottom];
Cara yang bahkan lebih cepat (dan lebih kotor) untuk melakukannya adalah dengan mengatur mode jeda baris UILabel ke "Klip" dan menambahkan sejumlah baris baru.
myLabel.lineBreakMode = UILineBreakModeClip;
myLabel.text = [displayString stringByAppendingString:"\n\n\n\n"];
Solusi ini tidak akan bekerja untuk semua orang - khususnya, jika Anda masih ingin menunjukkan "..." di akhir string Anda jika melebihi jumlah baris yang Anda tampilkan, Anda harus menggunakan salah satu dari bit kode yang lebih panjang - tetapi untuk banyak kasus ini akan memberi Anda apa yang Anda butuhkan.
UILineBreakModeWordWrap
sebagai gantinya.
Pendekatan termudah menggunakan Storyboard:
Sematkan Label di StackView dan atur dua atribut berikut dari StackView di Attribute Inspector:
1 Axis
sampai Horizontal
,
2- Alignment
keTop
UILabel
ke dalam beberapa UIView
subclass (dataran UIView
biasanya cukup) dan biarkan label itu tumbuh ke bawah arah. Terima kasih!
UILabel
dan biarkan StackView melakukan tugasnya. Terima kasih!
Alih-alih UILabel
Anda dapat menggunakan UITextField
yang memiliki opsi perataan vertikal:
textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
textField.userInteractionEnabled = NO; // Don't allow interaction
Saya sudah berjuang dengan yang ini untuk waktu yang lama dan saya ingin berbagi solusi.
Ini akan memberi Anda UILabel
yang akan menyusutkan teks secara otomatis ke 0,5 skala dan memusatkan teks secara vertikal. Opsi ini juga tersedia di Storyboard / IB.
[labelObject setMinimumScaleFactor:0.5];
[labelObject setBaselineAdjustment:UIBaselineAdjustmentAlignCenters];
Buat kelas baru
LabelTopAlign
file .h
#import <UIKit/UIKit.h>
@interface KwLabelTopAlign : UILabel {
}
@end
file .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
Berikut ini adalah implementasi sederhana yang melakukan hal yang sama:
#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
solusi ini sebenarnya membuat teks UILabel
menempatkan apa pun di atas, bahkan jika Anda secara dinamis mengganti teks yang lebih pendek dengan yang lebih lama atau sebaliknya.
Di Interface Builder
UILabel
ke ukuran Teks sebesar mungkinLines
ke '0' di Atribut InspekturDalam kode Anda
sizeToFit
label AndaCuplikan Kode:
self.myLabel.text = @"Short Title";
[self.myLabel sizeToFit];
Untuk UI Adaptif (iOS8 atau setelahnya), Penyelarasan Vertikal UILabel harus diatur dari StoryBoard dengan Mengubah properti
noOfLines
= 0` dan
Kendala
Menyesuaikan UILabel LefMargin, RightMargin, dan Top Margin Constraints.
Ubah
Content Compression Resistance Priority For Vertical
= 1000` Sehingga Vertikal> Horisontal.
Diedit:
noOfLines=0
dan kendala-kendala berikut cukup untuk mencapai hasil yang diinginkan.
Buat subkelas UILabel. Bekerja seperti pesona:
// 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
Seperti yang dibahas di sini .
Saya menulis fungsi util untuk mencapai tujuan ini. Anda dapat melihatnya:
// sesuaikan ketinggian label multi-garis untuk membuatnya sejajar vertikal dengan atas + (void) alignLabelWithTop: (UILabel *) label { CGSize maxSize = CGSizeMake (label.frame.size.width, 999); label.adjustsFontSizeToFitWidth = TIDAK; // dapatkan tinggi sebenarnya CGSize actualSize = [label.text sizeWithFont: label.font constrainedToSize: maxSize lineBreakMode: label.lineBreakMode]; CGRect rect = label.frame; rect.size.height = actualSize.height; label.frame = rect; }
.Cara Penggunaan? (Jika lblHello dibuat oleh pembangun Antarmuka, maka saya lewati beberapa detail atribut 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];
Saya juga menulisnya di blog saya sebagai artikel: http://fstoke.me/blog/?p=2819
Saya perlu beberapa saat untuk membaca kode, serta kode di halaman yang diperkenalkan, dan menemukan bahwa mereka semua mencoba untuk mengubah ukuran bingkai label, sehingga perataan vertikal pusat default tidak akan muncul.
Namun, dalam beberapa kasus kami ingin label untuk menempati semua ruang itu, bahkan jika label memiliki begitu banyak teks (misalnya beberapa baris dengan tinggi yang sama).
Di sini, saya menggunakan cara alternatif untuk menyelesaikannya, cukup dengan menempelkan baris baru ke akhir label (harap dicatat bahwa saya benar-benar mewarisi UILabel
, tetapi tidak perlu):
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 "];
}
Saya mengambil saran di sini dan membuat tampilan yang dapat membungkus sebuah UILabel dan akan mengukurnya dan mengatur jumlah baris sehingga bagian atas selaras. Sederhananya UILabel sebagai 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
Anda dapat menggunakan TTTAttributedLabel , ini mendukung perataan vertikal.
@property (nonatomic) TTTAttributedLabel* label;
<...>
//view's or viewController's init method
_label.verticalAlignment = TTTAttributedLabelVerticalAlignmentTop;
Saya telah menemukan jawaban atas pertanyaan ini sekarang agak ketinggalan zaman, jadi menambahkan ini untuk penggemar tata letak otomatis di luar sana.
Tata letak otomatis membuat masalah ini cukup sepele. Dengan asumsi kami menambahkan label UIView *view
, kode berikut akan menyelesaikan ini:
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}]];
Tinggi label akan dihitung secara otomatis (menggunakannya intrinsicContentSize
) dan label akan diposisikan ujung ke ujung secara horizontal, di bagian atas view
.
Saya telah menggunakan banyak metode di atas, dan hanya ingin menambahkan pendekatan cepat dan kotor yang saya gunakan:
myLabel.text = [NSString stringWithFormat:@"%@\n\n\n\n\n\n\n\n\n",@"My label text string"];
Pastikan jumlah baris baru dalam string akan menyebabkan teks apa pun mengisi ruang vertikal yang tersedia, dan mengatur label UIL untuk memotong teks yang meluap.
Karena kadang-kadang cukup baik cukup baik .
UITextView
itu dapat dipanggil dlopen
untuk mendukung input teks. Ini dapat menyebabkan kelambatan utama pada utas UI, sehingga pendekatan ini jauh lebih hebat!
Saya ingin memiliki label yang dapat memiliki multi-baris, ukuran font minimum, dan terpusat secara horizontal dan vertikal dalam tampilan induknya. Saya menambahkan label saya ke tampilan saya secara terprogram:
- (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];
}
Dan kemudian ketika saya ingin mengubah teks label saya ...
- (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];
}
Semoga itu bisa membantu seseorang!
FXLabel (on github) melakukan ini di luar kotak dengan mengatur label.contentMode
ke UIViewContentModeTop
. Komponen ini tidak dibuat oleh saya, tetapi merupakan komponen yang sering saya gunakan dan memiliki banyak fitur, dan tampaknya berfungsi dengan baik.
bagi siapa pun yang membaca ini karena teks di dalam label Anda tidak terpusat secara vertikal, perlu diingat bahwa beberapa jenis font tidak dirancang sama. misalnya, jika Anda membuat label dengan ukuran zapfino 16, Anda akan melihat teksnya tidak terpusat sempurna secara vertikal.
namun, bekerja dengan helvetica akan memusatkan teks Anda secara vertikal.
Gunakan textRect(forBounds:limitedToNumberOfLines:)
.
class TopAlignedLabel: UILabel {
override func drawText(in rect: CGRect) {
let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines)
super.drawText(in: textRect)
}
}
Subkelas UILabel dan batasi persegi panjang gambar, seperti ini:
- (void)drawTextInRect:(CGRect)rect
{
CGSize sizeThatFits = [self sizeThatFits:rect.size];
rect.size.height = MIN(rect.size.height, sizeThatFits.height);
[super drawTextInRect:rect];
}
Saya mencoba solusi yang melibatkan pad baris baru dan mengalami perilaku yang salah dalam beberapa kasus. Dalam pengalaman saya, lebih mudah untuk membatasi gambar persegi seperti di atas daripada mengacaukan numberOfLines
.
PS Anda dapat membayangkan dengan mudah mendukung UIViewContentMode dengan cara ini:
- (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];
}
Selama Anda tidak melakukan apapun tugas yang kompleks, Anda dapat menggunakan UITextView
bukan UILabels
.
Nonaktifkan gulir.
Jika Anda ingin teks ditampilkan sepenuhnya hanya pengguna sizeToFit
dan sizeThatFits:
metode
Dengan cepat,
let myLabel : UILabel!
Untuk membuat teks dari Label Anda agar sesuai dengan layar dan itu di atas
myLabel.sizeToFit()
Untuk membuat font label Anda agar sesuai dengan lebar layar atau ukuran lebar tertentu.
myLabel.adjustsFontSizeToFitWidth = YES
dan beberapa Penjajaran teks untuk label:
myLabel.textAlignment = .center
myLabel.textAlignment = .left
myLabel.textAlignment = .right
myLabel.textAlignment = .Natural
myLabel.textAlignment = .Justified
[myLabel sizeToFit]
. Terima kasih!
Ini adalah solusi lama, gunakan autolayout di iOS> = 6
Solusi saya:
@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