Padding a UILabel
, solusi lengkap. Diperbarui untuk 2020.
Ternyata ada tiga hal yang harus dilakukan.
1. Harus memanggil textRect # forBounds dengan ukuran baru yang lebih kecil
2. Harus mengganti drawText dengan ukuran baru yang lebih kecil
3. Jika sel berukuran dinamis, harus menyesuaikan intrinsicContentSize
Dalam contoh khas di bawah ini, unit teks dalam tampilan tabel, tampilan tumpukan atau konstruksi serupa, yang memberikan lebar tetap . Dalam contoh ini kami ingin menambahkan 60,20,20,24.
Jadi, kita ambil intrinsicContentSize "yang ada" dan benar-benar menambahkan 80 ke ketinggian .
Mengulang ...
Anda harus benar-benar "menghitung" ketinggian yang dihitung "sejauh ini" oleh mesin, dan mengubah nilainya.
Saya menemukan proses itu membingungkan, tetapi, itulah cara kerjanya. Bagi saya, Apple harus mengekspos panggilan bernama "perhitungan tinggi pendahuluan".
Kedua, kita harus benar-benar menggunakan panggilan textRect # forBounds dengan ukuran baru yang lebih kecil .
Jadi dalam textRect # forBounds kita pertama membuat ukuran yang lebih kecil dan kemudian memanggil super.
Waspada! Anda harus menelepon super setelah , bukan sebelumnya!
Jika Anda hati-hati menyelidiki semua upaya dan diskusi di halaman ini, itulah masalah yang sebenarnya. Perhatikan beberapa solusi "tampaknya hampir berhasil" tetapi kemudian seseorang akan melaporkan bahwa dalam situasi tertentu itu tidak akan berhasil. Ini memang alasan yang tepat - membingungkan Anda harus "memanggil super sesudahnya", bukan sebelumnya.
Jadi, jika Anda memanggil super itu "dalam urutan yang salah", biasanya berfungsi, tetapi tidak untuk panjang teks tertentu tertentu .
Berikut ini adalah contoh visual yang tepat dari "salah melakukan super pertama":
Perhatikan bahwa margin 60,20,20,24 sudah benar TETAPI perhitungan ukurannya sebenarnya salah, karena dilakukan dengan pola "super first" di textRect # forBounds.
Tetap:
Perhatikan bahwa hanya sekarang mesin textRect # forBounds tahu cara melakukan perhitungan dengan benar :
Akhirnya!
Sekali lagi, dalam contoh ini, UILabel digunakan dalam situasi tipikal di mana lebar ditetapkan. Jadi dalam intrinsicContentSize kita harus "menambahkan" tinggi ekstra keseluruhan yang kita inginkan. (Anda tidak perlu "menambahkan" dengan cara apa pun ke lebar, itu akan menjadi tidak berarti karena sudah diperbaiki.)
Kemudian di textRect # forBounds Anda mendapatkan batasan "disarankan sejauh ini" dengan autolayout, Anda kurangi margin Anda, dan hanya dengan itu memanggil lagi ke mesin textRect # forBounds, yaitu di super, yang akan memberi Anda hasil.
Akhirnya dan cukup di drawText Anda tentu saja menggambar di kotak kecil yang sama.
Fiuh!
let UIEI = UIEdgeInsets(top: 60, left: 20, bottom: 20, right: 24) // as desired
override var intrinsicContentSize:CGSize {
numberOfLines = 0 // don't forget!
var s = super.intrinsicContentSize
s.height = s.height + UIEI.top + UIEI.bottom
s.width = s.width + UIEI.left + UIEI.right
return s
}
override func drawText(in rect:CGRect) {
let r = rect.inset(by: UIEI)
super.drawText(in: r)
}
override func textRect(forBounds bounds:CGRect,
limitedToNumberOfLines n:Int) -> CGRect {
let b = bounds
let tr = b.inset(by: UIEI)
let ctr = super.textRect(forBounds: tr, limitedToNumberOfLines: 0)
// that line of code MUST be LAST in this function, NOT first
return ctr
}
Sekali lagi. Perhatikan bahwa jawaban pada QA ini dan lainnya yang "hampir" benar mengalami masalah pada gambar pertama di atas - "super ada di tempat yang salah" . Anda harus memaksa ukuran lebih besar di intrinsicContentSize dan kemudian di textRect # forBounds Anda harus terlebih dahulu mengecilkan batas saran pertama dan kemudian memanggil super.
Ringkasan: Anda harus "memanggil super terakhir " di textRect # forBounds
Itulah rahasianya.
Perhatikan bahwa Anda tidak perlu dan tidak perlu memanggil tambahan yang tidak valid, sizeThatFits, needsLayout atau panggilan pemaksaan lainnya. Solusi yang benar harus bekerja dengan baik dalam siklus penarikan autolayout normal.
Tip:
Jika Anda bekerja dengan font monospace, inilah tip yang bagus: https://stackoverflow.com/a/59813420/294884