UILabel - metne sığacak otomatik boyutlu etiket?


144

UILabel kutusunu / sınırlarını içerilen metne sığacak şekilde otomatik olarak yeniden boyutlandırmak mümkün müdür? (Ekrandan daha büyük olup olmadığını umursamıyorum)

Yani bir kullanıcı "merhaba" veya "benim adım gerçekten uzun girerse, bu kutuya sığmasını istiyorum", asla kesilmez ve etiket buna göre 'genişletilir'?


Herkes bana hızlı kodları sağlama konusunda yardım ..
Angel F Syrus

Yanıtlar:


98

Lütfen UILabelçok benzer bir şey için bir kategori yaptığım özgeçmişime göz atın , kategorim UILabeltüm içeriği göstermek için yüksekliğini uzatır: https://gist.github.com/1005520

Veya bu gönderiye göz atın: https://stackoverflow.com/a/7242981/662605

Bu, yüksekliği uzatır, ancak başka bir şekilde çalışmak ve genişliği böyle bir şeyle genişletmek için kolayca değiştirebilirsiniz, yani ne yapmak istediğinize inanıyorum:

@implementation UILabel (dynamicSizeMeWidth)

- (void)resizeToStretch{
    float width = [self expectedWidth];
    CGRect newFrame = [self frame];
    newFrame.size.width = width;
    [self setFrame:newFrame];
}

- (float)expectedWidth{
    [self setNumberOfLines:1];

    CGSize maximumLabelSize = CGSizeMake(CGRectGetWidth(self.bounds), CGFLOAT_MAX);

    CGSize expectedLabelSize = [[self text] sizeWithFont:[self font] 
                                            constrainedToSize:maximumLabelSize
                                            lineBreakMode:[self lineBreakMode]]; 
    return expectedLabelSize.width;
}

@end

Sınıfta bulunan sizeToFityöntemi daha basit bir şekilde kullanabilirsiniz UIView, ancak satır sayısını güvende olacak şekilde 1 olarak ayarlayabilirsiniz.


iOS 6 güncellemesi

AutoLayout kullanıyorsanız, yerleşik bir çözümünüz vardır. Satır sayısını 0 olarak ayarladığınızda, çerçeve etiketinizi metninize sığacak şekilde yeniden boyutlandıracaktır (daha fazla yükseklik ekleyerek).


iOS 8 güncellemesi

sizeWithFont:kullanımdan kaldırıldı, sizeWithAttributes:bunun yerine şunu kullanın:

- (float)expectedWidth{
    [self setNumberOfLines:1];

    CGSize expectedLabelSize = [[self text] sizeWithAttributes:@{NSFontAttributeName:self.font}];

    return expectedLabelSize.width;
}

8
İOS 6 AutoLayout yöntemini kullanarak, etiketimde kurtulamadığım bir yükseklik kısıtlaması buldum. Yükseklik sınırlamasının 'Büyüktür ya da Eşittir' olarak ilişkisinin ayarlanması yüksekliğin büyümesine izin verdi.
Michael Luton

2
sizeWithFont: constrainedToSize: lineBreakMode: ios 7'de depricated yöntem
Karan Alangat

1
Metin daha az / daha fazla olduğunda UILabel kendini yeniden boyutlandırmaz. Otomatik düzen kullanıyorum. UILabel Yapımı Denendi ancak cellForRowAtIndex her başlatıldığında oluşturulur. Birçok şey denedim. Benim için hiçbir şey çalışmıyor. Uilabel'in arka planı aynı genişliği alır. Yardım !!!
coreDeviOS

@Daniel = 0 sayısını ayarladım, ama çalışmıyor. Yatay ve dikey merkezin kısıtlamalarını belirledim. Yaptığım ekstra bir şey UILABEL'in bir alt sınıfının yapılması ve bu Etiket için kullanılması
Jasmeet

Autolayout ile en basit çözüm: (1) Satırları 0 olarak ayarlayın, (2) Genişlik sınırını Sabit 0 ile "Büyüktür veya Eşit" olarak ayarlayın, (3) Yükseklik sınırını Sabit 0 ile "Büyüktür veya Eşit" olarak ayarlayın, ( 4) Normalde yaptığınız gibi hizalayın, örneğin yatay ve dikey olarak ortalayarak.
Erik van der Neut

76

Kullanmak [label sizeToFit];Daniels Kategorisinden aynı sonucu elde edecektir.

Her ne kadar otomatik yerleşimi kullanmanızı ve kısıtlamalara göre etiketin kendisini yeniden boyutlandırmasını öneriyorum.


3
Swift kullanırken bunu dispatch_async (dispatch_get_main_queue (), {}) kullanarak ana iş parçacığında çalıştırmak zorunda kaldım;
Zeezer

@Zeezer nedenini biliyor musun?
FurloSK

13
@FurloSK Kullanıcı arayüzündeki tüm değişiklikler ana iş parçacığında yapılmalıdır.
Guilherme Torres Castro

32

UILabelMetin boyutuna göre küçülüp genişlemesini istiyorsak, otomatik yerleşimli film şeridi en iyi seçenektir. Bunu başarmak için adımlar aşağıdadır

adımlar

  1. UILabel'ı görünüm denetleyicisine yerleştirin ve istediğiniz yere yerleştirin. Ayrıca mülkiyet 0için koydu .numberOfLinesUILabel

  2. Üst, Lider ve Sondaki boşluk pimi kısıtlamasını verin.

resim açıklamasını buraya girin

  1. Şimdi uyarı verecektir, Sarı oka tıklayın.

resim açıklamasını buraya girin

  1. Tıklayın Update Frameve tıklayın Fix Misplacement. Şimdi bu UILabel metin daha küçükse küçülür ve metin daha büyükse genişler.

1
Yerelleştirme için test yapmadım, ancak bunun için de işe yarayacak.
Yogesh Suthar

2
"Tercih edilen genişlik" "Açık" onay kutusunun işaretini kaldırıncaya kadar mevcut bir projeyle çalışmak için bunu alamadım, sonra hepsi iyi çalıştı.
zorro2b

25

Bu, diğer cevapların bazıları kadar karmaşık değildir.

resim açıklamasını buraya girin

Sol ve üst kenarları sabitleyin

Etiketin sol ve üst taraflarını sabitlemek için kısıtlamalar eklemek için otomatik düzeni kullanmanız yeterlidir.

resim açıklamasını buraya girin

Bundan sonra otomatik olarak yeniden boyutlandırılacaktır.

notlar

  • Genişlik ve yükseklik için sınırlama eklemeyin. Etiketlerin kendine özgü , metin içeriklerine göre boyuttadır.
  • Bu cevap için teşekkürler yardım .
  • sizeToFitOtomatik düzeni kullanırken ayar yapmaya gerek yoktur . Örnek proje için tam kodum burada:

    import UIKit
    class ViewController: UIViewController {
    
        @IBOutlet weak var myLabel: UILabel!
    
        @IBAction func changeTextButtonTapped(sender: UIButton) {
            myLabel.text = "my name is really long i want it to fit in this box"
        }
    }
  • Etiketinizin satır kaydırmasını istiyorsanız, IB'de satır sayısını 0 olarak ayarlayın ve myLabel.preferredMaxLayoutWidth = 150 // or whateverkodu ekleyin . (Ayrıca, etiket yüksekliği arttığında düğmenin aşağı doğru hareket etmesi için düğmemi etiketin altına sabitledim.)

resim açıklamasını buraya girin

  • Etiketleri dinamik olarak boyutlandırmak istiyorsanız, bu cevabaUITableViewCell bakın .

resim açıklamasını buraya girin


Merhaba, yeniden boyutlandırılmış etiketi aldım, ancak hücre yüksekliğini nasıl yeniden boyutlandıracağımı anlamıyorum. Lütfen hücre yüksekliğini nasıl yeniden boyutlandıracağımı bana bildirir misiniz?
Vivek

@Vivek, yükseklikte ayarlanmış bir kısıtlamanız olmadığı sürece otomatik olarak yeniden boyutlandırılmalıdır.
Suragch

Evet, Ama nasıl özel hücre kullandığımda ve hücresine 2 etiket koyduğumda bu mümkün.
Vivek

@Vivek, üzgünüm, sorunuzu yanlış okudum. Bu yanıtı inceleyerek zaten bir etiket aldınız mı ?
Suragch


5

Daniel'in cevabını temel alarak bazı yöntemler oluşturdum.

-(CGFloat)heightForLabel:(UILabel *)label withText:(NSString *)text
{
    CGSize maximumLabelSize     = CGSizeMake(290, FLT_MAX);

    CGSize expectedLabelSize    = [text sizeWithFont:label.font
                                constrainedToSize:maximumLabelSize
                                    lineBreakMode:label.lineBreakMode];

    return expectedLabelSize.height;
}

-(void)resizeHeightToFitForLabel:(UILabel *)label
{
    CGRect newFrame         = label.frame;
    newFrame.size.height    = [self heightForLabel:label withText:label.text];
    label.frame             = newFrame;
}

-(void)resizeHeightToFitForLabel:(UILabel *)label withText:(NSString *)text
{
    label.text              = text;
    [self resizeHeightToFitForLabel:label];
}

5

İşte bulduğum durumum için işe yarıyor:

1) UILabel yüksekliğinin otomatik yerleşimi kullanan bir = = 0 kısıtlaması vardır. Genişlik sabittir. 2) Metni, o noktada zaten bir denetime sahip olan UILabel'e atayın (bunun ne kadar hayati olduğundan emin değilim). 3) Sonra şunları yapın:

    label.sizeToFit()
    label.layoutIfNeeded()

Etiketin yüksekliği artık uygun şekilde ayarlanmıştır.


3
@implementation UILabel (UILabel_Auto)

- (void)adjustHeight {

    if (self.text == nil) {
        self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.bounds.size.width, 0);
        return;
    }

    CGSize aSize = self.bounds.size;
    CGSize tmpSize = CGRectInfinite.size;
    tmpSize.width = aSize.width;

    tmpSize = [self.text sizeWithFont:self.font constrainedToSize:tmpSize];

    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, aSize.width, tmpSize.height);
}

@end

Bu kategori yöntemidir. UILabel'ın yüksekliğini ayarlamak için önce bu yöntemi çağırmak yerine metni ayarlamanız gerekir.


2

Etiketinizi iki şekilde kullanarak metne ve diğer ilgili denetimlere göre boyutlandırabilirsiniz.

  1. İOS 7.0 ve üstü için

    CGSize labelTextSize = [labelText boundingRectWithSize:CGSizeMake(labelsWidth, MAXFLOAT)
                                              options:NSStringDrawingUsesLineFragmentOrigin
                                           attributes:@{
                                                        NSFontAttributeName : labelFont
                                                        }
                                              context:nil].size;

iOS 7.0'dan önce bu, etiket boyutunu hesaplamak için kullanılabilir

CGSize labelTextSize = [label.text sizeWithFont:label.font 
                            constrainedToSize:CGSizeMake(label.frame.size.width, MAXFLOAT)  
                                lineBreakMode:NSLineBreakByWordWrapping];

// labelTextHeight'a dayalı diğer denetimleri yeniden çerçevele

CGFloat labelTextHeight = labelTextSize.height;
  1. Etiket metninin boyutunu hesaplamak istemiyorsanız UILabel as- örneğinde -sizeToFit kullanabilirsiniz.

    [label setNumberOfLines:0]; // for multiline label
    [label setText:@"label text to set"];
    [label sizeToFit];// call this to fit size of the label according to text

// bundan sonra diğer ilgili kontrolleri yeniden çerçevelemek için etiket çerçevesini alabilirsiniz


2
  1. Film şeridine eksik kısıtlamalar ekleyin.
  2. Film şeridinde UILabel'i seçin ve "Çizgi" niteliklerini 0 olarak ayarlayın.
  3. Ref id: label ile UILabel'i Controller.h dosyasına aktarın
  4. Controller.m ve [label sizeToFit];viewDidLoad'a ekleyin

1

Otomatik düzen ile ilgili büyük sorunlar yaşadım. Tablo hücresinin içinde iki kap var. İkinci kap, Öğe açıklamasına bağlı olarak yeniden boyutlandırılır (0 - 1000 karakter) ve satır bunlara göre yeniden boyutlandırılmalıdır.

Eksik bileşen açıklama için alt sınırlamadır.

Ben dinamik elemanının alt sınırlaması değiştirdik = 0 için > = 0 .


Bu hayatımı kurtardı. Takip etmeye çalışıyorsanız: github.com/honghaoz/… bu doğru cevaptır.
Justin Fyles

0

Her zaman uyar! :)

    name.text = @"Hi this the text I want to fit to"
    UIFont * font = 14.0f;
    CGSize size = [name.text sizeWithAttributes:@{NSFontAttributeName: font}];
    nameOfAssessment.frame = CGRectMake(400, 0, size.width, 44);
    nameOfAssessment.font = [UIFont systemFontOfSize:font];

0

bir satır çıktısı gösterebilir ve ardından Line = 0 özelliğini ayarlayabilir ve birden çok satır çıktısı gösterebilir ve daha sonra Line = 1 ve daha fazla özelliğini ayarlayabilirsiniz

[self.yourLableName sizeToFit];

-1

Bu yaklaşım da var:

[self.myLabel changeTextWithAutoHeight:self.myStringToAssignToLabel width:180.0f];

Bu cevabı reddeden ben değildim ama sadece bir changeTextWithAutoHeight:width:yöntem göremediğimi belirtmek istedim UILabel. Lütfen bu yöntemi UIKit belgelerinde nerede bulabileceğinize bir link verebilir misiniz?
Adil Hussain
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.