Sesuaikan tinggi UILabel ke teks

112

Saya memiliki beberapa label yang ingin saya sesuaikan tingginya dengan teks, ini adalah kode yang saya tulis untuk ini sekarang

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
}

EDIT:

Masalahnya bukan pada bagian kode ini, jadi perbaikan saya ada pada pertanyaan itu sendiri. Mungkin masih berguna untuk orang lain!

TheBurgerShot
sumber
Lihatlah tambahan NSString UIKit, ada metode untuk menghitung ukuran yang Anda butuhkan tanpa membuat UILabel.
Vladimir Gritsenko
@VladimirGritsenko metode 'sizeWithFont' tidak tersedia di Swift :(
TheBurgerShot
Saya akui saya bukan ahli Swift, tapi saya yakin Anda bisa menambahkan metode penghubung Anda sendiri. Masih layak untuk dibuat UILabel untuk menghitung ukuran.
Vladimir Gritsenko
@TheBurgerShot sizeWithFontmungkin tidak tersedia untuk Swift Stringtetapi tersedia di NSStringAnda masih dapat memanggilnya di sana.
Anorak
Pada akhirnya, kesalahannya adalah sesuatu yang berbeda dan tidak ada hubungannya dengan metode ini. Padahal ini mungkin masih bisa membantu orang lain.
TheBurgerShot

Jawaban:

189

Saya baru saja meletakkan ini di taman bermain dan berhasil untuk saya.

Diperbarui untuk Swift 4.0

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)

Cepat 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
}

masukkan deskripsi gambar di sini

Anorak
sumber
ini berfungsi dengan baik untuk saya juga di taman bermain, kesalahan tampaknya tidak terjadi di tempat khusus ini, ketika saya menghapus penggunaan metode ini, itu akan mengeluh tentang beberapa println atau hanya baris dengan hanya komentar (kemudian dikatakan EXC_BAD_ACCESS code = 2 juga)
TheBurgerShot
6
Ini berfungsi di taman bermain, tetapi tidak ada ukuran yang terjadi seperti yang diinginkan di dalam pengontrol tampilan di
XCode
1
Saya agak ragu untuk membuat ukuran baru UILabel; jika metode ini digunakan di dalam layoutSubviewsdengan kecenderungan untuk dipanggil beberapa kali per tata letak lengkap, pembuatan objek tambahan dapat menyebabkan penundaan yang nyata, terutama selama pengguliran.
Zorayr
biarkan textRect = textString.boundingRectWithSize (CGSizeMake (320, 2000), opsi: .UsesLineFragmentOrigin, atribut: textAttributes, konteks: nil)
Siddharth Pancholi
Saya tidak dapat memanggil fungsi ini di pengontrol tampilan saya ... Dapatkah Anda menyarankan saya apa kemungkinan alasannya?
Rouny
64

Jika Anda menggunakan AutoLayout , Anda dapat menyesuaikan UILabelketinggian hanya dengan config UI.

Untuk iOS8 atau lebih tinggi

  • Tetapkan batasan di depan / di belakang untuk Anda UILabel
  • Dan ubah garis UILabeldari 1 menjadi 0

masukkan deskripsi gambar di sini

Untuk iOS7

  • Pertama , Anda perlu menambahkan ketinggian untukUILabel
  • Kemudian , ubah Relasi dari EqualmenjadiGreater than or Equal

masukkan deskripsi gambar di sini

  • Terakhir , ubah garis UILabeldari 1 menjadi 0

masukkan deskripsi gambar di sini

Anda UILabelakan secara otomatis menambah tinggi tergantung pada teksnya

Phan Van Linh
sumber
2
Dan jika labelnya ada di dalam sel. Kapan dan bagaimana Anda akan meningkatkan tinggi sel?
oyalhi
1
@oyalhi, jika label Anda ada di dalam sel tampilan tabel, silakan lihat kiriman saya yang lain stackoverflow.com/a/36277840/5381331
Phan Van Linh
3
Ini bekerja dengan sempurna untuk saya! Siapkan batasan, dan itu akan bekerja dengan baik!
Bill Thompson
2
tidak bekerja untuk saya ... kata "Label" dalam UILabel membuat tinggi = 20. Tetap 20 setelah pengaturan ini.
gadget00
9

Saya membuat ekstensi ini jika Anda mau

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

Saya memiliki solusi kerja yang kuat.

dalam tata letak

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

di penyetel teks:

    _title.text = newValue
    setNeedsLayout()

UPD. tentunya dengan setting UILabel ini:

    _title.lineBreakMode = .ByWordWrapping
    _title.numberOfLines = 0
dimpiax
sumber
6

Hanya dengan mengatur:

label.numberOfLines = 0

Label secara otomatis menyesuaikan tingginya berdasarkan jumlah teks yang dimasukkan.

Yordania Amman
sumber
27
Ini tidak membuat UILabel menyesuaikan tingginya.
TheBurgerShot
6

berdasarkan jawaban Anorak, saya juga setuju dengan perhatian Zorayr, jadi saya menambahkan beberapa baris untuk menghapus UILabel dan hanya mengembalikan CGFloat, saya tidak tahu apakah itu membantu karena kode asli tidak menambahkan UIabel, tetapi itu tidak membuang kesalahan, jadi saya menggunakan kode di bawah ini:

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
}
LeftyT
sumber
5

Dalam 4.1 cepat dan Xcode 9.4.1

Hanya 3 langkah

Langkah 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
}

Langkah 2)

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

Langkah 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)
iOS
sumber
5

Solusi yang disarankan oleh Anorak sebagai properti yang dihitung dalam ekstensi untuk UILabel:

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
         }
    }
}

Pemakaian:

self.brandModelLabel.frame.size.height = self.brandModelLabel.optimalHeight
Philipp Otto
sumber
Solusi bagus! Terima kasih :-)
Cristina
Tak dapat menetapkan ke properti: 'height' adalah properti get-only.
Amg91
4

Mengikuti jawaban @Anorak, saya menambahkan ekstensi ini ke String dan mengirim inset sebagai parameter, karena sering kali Anda memerlukan padding ke teks Anda. Bagaimanapun, mungkin beberapa Anda akan menemukan ini berguna.

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
    }
}
Lirik
sumber
label.lineBreakMode = NSLineBreakMode.ByWordWrapping baris ini membantu saya, terima kasih.
Coder_A_D
3

Berikut adalah cara menghitung tinggi teks di Swift. Anda kemudian bisa mendapatkan tinggi dari persegi dan mengatur ketinggian batasan label atau textView, dll.

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)
Collin
sumber
3

panggil saja metode ini di mana Anda membutuhkan Tinggi dinamis untuk label

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
}
Shubham bairagi
sumber
3

Swift 4.0.0

self.messageLabel = UILabel (bingkai: CGRect (x: 70, y: 60, lebar: UIScreen.main.bounds.width - 80, tinggi: 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()

Blockquote NSParagraphStyle.LineBreakMode, berlaku untuk seluruh paragraf, bukan kata-kata dalam paragraf. Properti ini berlaku selama penggambaran normal dan dalam kasus di mana ukuran font harus dikurangi agar pas dengan teks label dalam kotak pembatasnya. Properti ini disetel ke byTruncatingTail secara default.

Tautan ini menjelaskan cara papan cerita untuk melakukan hal yang sama

7ur7l3
sumber
2
Jawaban hanya kode tidak dianggap sebagai praktik yang baik. Harap pertimbangkan untuk menambahkan beberapa penjelasan tentang bagaimana jawaban Anda menjawab pertanyaan tersebut.
Yannis
2

Swift 4.0.0

Alih-alih menghitung tinggi teks / label, saya hanya mengubah ukuran label setelah memasukkan teks (dinamis).

Asumsikan bahwa myLabel adalah UILabel yang dimaksud:

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

Dan sekarang sampai pada bagian yang menyenangkan:

var myLabelText: String = "" {
   didSet {
      myLabel.text = myLabelText
      myLabel.sizeToFit()
   }
}
Patrick J.
sumber
2

The Swift 4.1 metode penyuluhan dengan tinggi label menghitung:

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
    }

}

sumber
1

Swift 5, cara papan cerita XCode 11. Saya pikir ini berfungsi untuk iOS 9 dan lebih tinggi. Misalnya Anda ingin label "Deskripsi" untuk mendapatkan tinggi dinamis, ikuti langkah-langkah berikut:

1) Pilih label deskripsi -> Pergi ke Attributes Inspector (ikon pensil), setel: Lines: 0 Line Break: Word Wrap

2) Pilih UILabel Anda dari storyboard dan masuk ke Size Inspector (ikon penggaris), 3) Turun ke "Prioritas Resistensi Kompresi Konten ke 1 untuk semua komponen UIView lainnya (label, tombol, tampilan gambar, dll) yang berinteraksi dengan label Anda.

Misalnya, saya memiliki UIImageView, Label Judul, dan Label Deskripsi secara vertikal dalam tampilan saya. Saya menetapkan Prioritas Resistensi Kompresi Konten ke UIImageView dan label judul ke 1 dan untuk label deskripsi ke 750. Ini akan membuat label deskripsi mengambil ketinggian sebanyak yang diperlukan.

Doci
sumber
0

Untuk membuat label dinamis dengan cepat, jangan beri konstar tinggi dan di storyboard buat label sejumlah baris 0 juga berikan batasan bawah dan ini adalah cara terbaik saya menangani label dinamis sesuai ukuran isinya.

Ranjeet Raushan
sumber
0

Anda juga bisa menggunakan sizeThatFitsfungsi.

Sebagai contoh:

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

Fitsyu
sumber