UILabel yüksekliğini metne ayarlayın


112

Yüksekliğini metne göre ayarlamak istediğim bazı etiketlerim var, bunun için şimdi yazdığım kod bu

func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat{
    let label:UILabel = UILabel(frame: CGRectMake(0, 0, width, CGFloat.max))
    label.numberOfLines = 0
    label.lineBreakMode = NSLineBreakMode.ByWordWrapping
    label.font = font
    label.text = text

    label.sizeToFit()
    return label.frame.height
}

DÜZENLE:

Sorun bu kod parçasında değildi, bu yüzden düzeltmem sorunun kendisinde. Yine de başkaları için faydalı olabilir!


NSString UIKit eklemelerine bir göz atın, bir UILabel oluşturmadan ihtiyacınız olan boyutu hesaplamak için yöntemler vardır.
Vladimir Gritsenko

@VladimirGritsenko 'sizeWithFont' yöntemleri Swift'de kullanılamaz :(
TheBurgerShot

Swift konusunda uzman olmadığımı kabul ediyorum, ancak kendi köprüleme yöntemlerinizi ekleyebileceğinize inanıyorum. Boyutu hesaplamak için UILabel oluşturmaya yine de değecektir.
Vladimir Gritsenko

@TheBurgerShot sizeWithFont, Swift için mevcut olmayabilir String, ancak kullanılabilir durumda. NSStringYine de bu şekilde arayabilmelisiniz.
Anorak

Sonuçta, hata farklı bir şeydi ve bu yöntemle hiçbir ilgisi yoktu. Yine de bu başkaları için yararlı olabilir.
TheBurgerShot

Yanıtlar:


189

Bunu bir oyun alanına koydum ve benim için çalışıyor.

Swift 4.0 için güncellendi

import UIKit

 func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat{
    let label:UILabel = UILabel(frame: CGRectMake(0, 0, width, CGFloat.greatestFiniteMagnitude))
    label.numberOfLines = 0
    label.lineBreakMode = NSLineBreakMode.byWordWrapping
    label.font = font
    label.text = text

    label.sizeToFit()
    return label.frame.height
}

let font = UIFont(name: "Helvetica", size: 20.0)

var height = heightForView("This is just a load of text", font: font, width: 100.0)

Swift 3:

func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat{
    let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
    label.numberOfLines = 0
    label.lineBreakMode = NSLineBreakMode.byWordWrapping
    label.font = font
    label.text = text
    label.sizeToFit()

    return label.frame.height
}

görüntü açıklamasını buraya girin


bu benim için de iyi çalışıyor, bu belirli yerde hata oluşmuyor, bu yöntemin kullanımlarını kaldırdığımda bazı println'ler veya sadece yorum içeren bir satır hakkında sızlanacak (sonra EXC_BAD_ACCESS kodu = diyor 2 de)
TheBurgerShot

6
Bir oyun alanında çalışır, ancak XCode 6.1
Unome

1
Yeni bir UILabelboyutlandırma oluşturmak için biraz tereddüt ediyorum ; Bu yöntem, layoutSubviewstam düzen başına birden çok kez çağrılma eğilimi ile içeride kullanılırsa , ekstra nesne oluşturma, özellikle kaydırma sırasında gözle görülür gecikmelere neden olabilir.
Zorayr

let textRect = textString.boundingRectWithSize (CGSizeMake (320, 2000), options: .UsesLineFragmentOrigin, attributes: textAttributes, context: nil)
Siddharth Pancholi

Görüntü denetleyicimde bu işlevi çağıramıyorum ... Olası nedeni ne olabilir bana önerebilir misiniz?
Rouny

64

AutoLayout kullanıyorsanız , UILabelyüksekliği yalnızca yapılandırma kullanıcı arayüzüyle ayarlayabilirsiniz .

İOS8 veya üstü için

  • Kısıtlama öncesini / sonunu ayarlayın. UILabel
  • Ve UILabel1'den 0'a satırlarını değiştirin

görüntü açıklamasını buraya girin

İOS7 için

  • Öncelikle , şunu içeren yükseklik eklemeniz gerekir:UILabel
  • Daha sonra , gelen ilişkisi değiştirmek EqualiçinGreater than or Equal

görüntü açıklamasını buraya girin

  • Son olarak , satırları UILabel1'den 0'a değiştirin

görüntü açıklamasını buraya girin

Kişisel UILabelirade otomatik metine göre yüksekliğini artırmak


2
Ve etiket bir hücrenin içindeyse. Buna göre hücre yüksekliğini ne zaman ve nasıl arttırırsınız?
oyalhi

1
@oyalhi, etiketiniz bir tablo görüntüleme hücresindeyse, lütfen diğer yazıma bakın stackoverflow.com/a/36277840/5381331
Phan Van Linh

3
Bu benim için mükemmel çalıştı! Kısıtlamaları ayarlayın ve düzgün çalışacaktır!
Bill Thompson

2
benim için çalışmıyor ... bir UILabel'deki "Etiket" kelimesi yüksekliği = 20 yapar. Bu ayardan sonra 20 kalır.
gadget00

9

İstersen bu uzantıyı oluşturuyorum

extension UILabel {
    func setSizeFont (sizeFont: CGFloat) {
        self.font =  UIFont(name: self.font.fontName, size: sizeFont)!
        self.sizeToFit()
    }
}

8

Güçlü bir çalışma çözümüm var.

in layoutSubviews:

    _title.frame = CGRect(x: 0, y: 0, width: bounds.width, height: 0)
    _title.sizeToFit()
    _title.frame.size = _title.bounds.size

metin belirleyicide:

    _title.text = newValue
    setNeedsLayout()

UPD. elbette bu UILabel ayarlarıyla:

    _title.lineBreakMode = .ByWordWrapping
    _title.numberOfLines = 0

6

Sadece ayarlayarak:

label.numberOfLines = 0

Etiket, girilen metin miktarına göre yüksekliğini otomatik olarak ayarlar.


27
Bu, UILabel'in yüksekliğini ayarlamasını sağlamaz.
TheBurgerShot

6

Anorak'ın cevabına dayanarak, Zorayr'ın endişesine de katılıyorum, bu yüzden UILabel'i kaldırmak ve yalnızca CGFloat'ı döndürmek için birkaç satır ekledim, orijinal kod UIabel'i eklemediğinden yardımcı olup olmadığını bilmiyorum, ancak hata atmıyor, bu yüzden aşağıdaki kodu kullanıyorum:

func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat{

    var currHeight:CGFloat!

    let label:UILabel = UILabel(frame: CGRectMake(0, 0, width, CGFloat.max))
    label.numberOfLines = 0
    label.lineBreakMode = NSLineBreakMode.ByWordWrapping
    label.font = font
    label.text = text
    label.sizeToFit()

    currHeight = label.frame.height
    label.removeFromSuperview()

    return currHeight
}

5

Swift 4.1 ve Xcode 9.4.1'de

Sadece 3 adım

Aşama 1)

//To calculate height for label based on text size and width
func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat {
    let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
    label.numberOfLines = 0
    label.lineBreakMode = NSLineBreakMode.byWordWrapping
    label.font = font
    label.text = text

    label.sizeToFit()
    return label.frame.height
}

Adım 2)

//Call this function
let height = heightForView(text: "This is your text", font: UIFont.systemFont(ofSize: 17), width: 300)
print(height)//Output : 41.0

Aşama 3)

//This is your label
let proNameLbl = UILabel(frame: CGRect(x: 0, y: 20, width: 300, height: height))
proNameLbl.text = "This is your text"
proNameLbl.font = UIFont.systemFont(ofSize: 17)
proNameLbl.numberOfLines = 0
proNameLbl.lineBreakMode = .byWordWrapping
infoView.addSubview(proNameLbl)

5

Anorak tarafından UILabel için bir uzantıda hesaplanmış bir özellik olarak önerilen çözüm:

extension UILabel
{
var optimalHeight : CGFloat
    {
        get
        {
            let label = UILabel(frame: CGRectMake(0, 0, self.frame.width, CGFloat.max))
            label.numberOfLines = 0
            label.lineBreakMode = self.lineBreakMode
            label.font = self.font
            label.text = self.text

            label.sizeToFit()

            return label.frame.height
         }
    }
}

Kullanımı:

self.brandModelLabel.frame.size.height = self.brandModelLabel.optimalHeight

Güzel çözüm! Teşekkür ederim :-)
Cristina

Özelliğe atanamaz: "yükseklik" yalnızca elde edilebilir bir özelliktir.
Amg91

4

@Anorak cevabını takiben, bu uzantıyı String'e ekledim ve parametre olarak bir ek gönderdim, çünkü çoğu zaman metninize bir dolguya ihtiyacınız olacak. Her neyse, belki bazılarınız bunu yararlı bulursunuz.

extension String {

    func heightForWithFont(font: UIFont, width: CGFloat, insets: UIEdgeInsets) -> CGFloat {

        let label:UILabel = UILabel(frame: CGRectMake(0, 0, width + insets.left + insets.right, CGFloat.max))
        label.numberOfLines = 0
        label.lineBreakMode = NSLineBreakMode.ByWordWrapping
        label.font = font
        label.text = self

        label.sizeToFit()
        return label.frame.height + insets.top + insets.bottom
    }
}

label.lineBreakMode = NSLineBreakMode.ByWordWrapping bu satırı bana teşekkür etti.
Coder_A_D

3

Swift'de metin yüksekliğinin nasıl hesaplanacağı aşağıda açıklanmıştır. Ardından yüksekliği dikten alabilir ve etiketin veya textView, vb. İçin kısıtlama yüksekliğini ayarlayabilirsiniz.

let font = UIFont(name: "HelveticaNeue", size: 25)!
let text = "This is some really long text just to test how it works for calculating heights in swift of string sizes. What if I add a couple lines of text?"

let textString = text as NSString

let textAttributes = [NSFontAttributeName: font]

let textRect = textString.boundingRectWithSize(CGSizeMake(320, 2000), options: .UsesLineFragmentOrigin, attributes: textAttributes, context: nil)

3

etiket için dinamik Yüksekliğe ihtiyacınız olan bu yöntemi çağırmanız yeterli

func getHeightforController(view: AnyObject) -> CGFloat {
    let tempView: UILabel = view as! UILabel
    var context: NSStringDrawingContext = NSStringDrawingContext()
    context.minimumScaleFactor = 0.8

    var width: CGFloat = tempView.frame.size.width

    width = ((UIScreen.mainScreen().bounds.width)/320)*width

    let size: CGSize = tempView.text!.boundingRectWithSize(CGSizeMake(width, 2000), options:NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: tempView.font], context: context).size as CGSize

    return size.height
}

3

Swift 4.0

self.messageLabel = UILabel (çerçeve: CGRect (x: 70, y: 60, genişlik: UIScreen.main.bounds.width - 80, yükseklik: 30)

messageLabel.text = message

messageLabel.lineBreakMode = .byWordWrapping //in versions below swift 3 (messageLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping)    
messageLabel.numberOfLines = 0 //To write any number of lines within a label scope

messageLabel.textAlignment = .center

messageLabel.textColor = UIColor.white

messageLabel.font = messageLabel.font.withSize(12)

messageLabel.sizeToFit()

Blok alıntı NSParagraphStyle.LineBreakMode, paragraf içindeki kelimelere değil, tüm paragraflara uygulanır. Bu özellik, hem normal çizim sırasında hem de yazı tipi boyutunun etiketin metnini sınırlayıcı kutusuna sığacak şekilde küçültülmesi gerektiği durumlarda etkindir. Bu özellik varsayılan olarak byTruncatingTail olarak ayarlanmıştır.

Bu bağlantı, aynı şeyi yapmanın film şeridi yolunu açıklıyor


2
Yalnızca kod yanıtları iyi uygulama olarak kabul edilmez. Lütfen cevabınızın soruyu nasıl ele aldığına dair bazı açıklamalar eklemeyi düşünün.
Yannis

2

Swift 4.0

Metin / etiket yüksekliğini hesaplamak yerine, (dinamik) metni ekledikten sonra etiketi yeniden boyutlandırıyorum.

MyLabel'in söz konusu UILabel olduğunu varsayarsak:

let myLabel = UILabel(frame: CGRect(x: 0, y: 0, width: *somewidth*, height: *placeholder, e.g. 20*))
myLabel.numberOfLines = 0
myLabel.lineBreakMode = .byWordWrapping
...

Ve şimdi eğlenceli kısım geliyor:

var myLabelText: String = "" {
   didSet {
      myLabel.text = myLabelText
      myLabel.sizeToFit()
   }
}

2

Swift 4.1 hesapla etiket yüksekliğine uzatma yöntemi:

extension UILabel {

    func heightForLabel(text:String, font:UIFont, width:CGFloat) -> CGFloat {
        let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
        label.numberOfLines = 0
        label.lineBreakMode = NSLineBreakMode.byWordWrapping
        label.font = font
        label.text = text

        label.sizeToFit()
        return label.frame.height
    }

}

1

Swift 5, XCode 11 film şeridi yolu. Bunun iOS 9 ve üstü için çalıştığını düşünüyorum. Örneğin, dinamik yüksekliği elde etmek için "Açıklama" etiketi istiyorsunuz, aşağıdaki adımları izleyin:

1) Açıklama etiketini seçin -> Nitelik Denetçisine gidin (kalem simgesi), ayarlayın: Satırlar: 0 Satır Sonu: Sözcük Kaydırma

2) Film şeridinden UILabel'ınızı seçin ve Boyut Denetçisi'ne gidin (cetvel simgesi), 3) Etiketinizle etkileşimde bulunan tüm diğer UIView bileşenleri (etiketler, düğmeler, görüntü görünümü vb.) İçin "İçerik Sıkıştırma Direnci Önceliği 1'e gidin.

Örneğin, görünümümde dikey olarak UIImageView, Başlık Etiketi ve Açıklama Etiketi var. İçerik Sıkıştırma Direnci Önceliğini UIImageView ve başlık etiketini 1 ve açıklama etiketi için 750 olarak ayarladım. Bu, gereken yüksekliği alması için bir açıklama etiketi oluşturacaktır.


0

Etiketi hızlı bir şekilde dinamik hale getirmek için, yükseklik kısıtlaması vermeyin ve film şeridinde etiket satır sayısı 0 da alt sınırlama verir ve bu, içerik boyutuna göre dinamik etiketi işlemenin en iyi yoludur.


0

Ayrıca sizeThatFitsişlevi de kullanabilirsiniz .

Örneğin:

label.sizeThatFits(superView.frame.size).height

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.