Saya mencoba untuk mendapatkan kotak untuk sebuah string yang dikaitkan, tetapi panggilan boundingRectWithSize tidak menghormati ukuran yang saya lewati dan mengembalikan kotak dengan tinggi baris tunggal sebagai lawan dari tinggi besar (itu adalah string panjang). Saya telah bereksperimen dengan mengirimkan nilai yang sangat besar untuk ketinggian dan juga 0 seperti pada kode di bawah ini, tetapi rect yang dikembalikan selalu sama.
CGRect paragraphRect = [attributedText boundingRectWithSize:CGSizeMake(300,0.0)
options:NSStringDrawingUsesDeviceMetrics
context:nil];
Apakah ini rusak, atau apakah saya perlu melakukan sesuatu yang lain untuk mengembalikannya dalam bentuk teks?
objective-c
nsattributedstring
RunLoop
sumber
sumber
lineBreakMode
?Jawaban:
Sepertinya Anda tidak memberikan opsi yang benar. Untuk label pembungkus, berikan setidaknya:
Catatan: jika lebar teks asli di bawah 300.f jika tidak akan ada pembungkus baris, jadi pastikan ukuran terikat sudah benar, jika tidak Anda akan tetap mendapatkan hasil yang salah.
sumber
ceilf(paragraphRect.size.height)
sehingga itu berhasil. Saya lupa ini sepanjang waktu dan bertanya-tanya mengapa label saya masih terpotong.boundingRectWithSize:
perhitungan saya dalam CGRectIntegral () yang akanCGRectIntegral rounds the rectangle’s origin downward and its size upward to the nearest whole integers
, dalam hal ini mengumpulkan tinggi dan lebar untuk memastikan tidak ada kliping terjadi jika tinggi atau lebar nilai fraksional.Untuk beberapa alasan, boundingRectWithSize selalu mengembalikan ukuran yang salah. Saya menemukan solusi. Ada metode untuk UItextView -sizeThatFits yang mengembalikan ukuran yang tepat untuk set teks. Jadi alih-alih menggunakan boundingRectWithSize, buat UITextView, dengan bingkai acak, dan panggil sizeThatFits dengan lebar masing-masing dan tinggi CGFLOAT_MAX. Ini mengembalikan ukuran yang akan memiliki ketinggian yang tepat.
Jika Anda menghitung ukuran dalam loop sementara, jangan lupa untuk menambahkannya dalam kumpulan autorelease, karena akan ada n jumlah UITextView yang dibuat, memori run time dari aplikasi akan meningkat jika kita tidak menggunakan autoreleasepool.
sumber
UITextView
waktu sebanyakheightForRowAtIndexPath
metode dipanggil? butuh waktuEd McManus tentu saja telah memberikan kunci agar ini berhasil. Saya menemukan sebuah kasus yang tidak berfungsi
rect tidak akan memiliki tinggi yang benar. Perhatikan bahwa anotherString (yang ditambahkan ke string ) diinisialisasi tanpa kamus atribut. Ini adalah penginisialisasi yang sah untuk anotherString tetapi boundingRectWithSize: tidak memberikan ukuran yang akurat dalam kasus ini.
sumber
NSMutableAttributedString
tanpa atribut dan saya mendapatkan ukuran yang salah.Keputusan akhir saya setelah penyelidikan panjang:
- boundingRectWithSize
fungsi mengembalikan ukuran yang benar hanya untuk urutan karakter tanpa gangguan! Dalam hal string berisi spasi atau sesuatu yang lain (disebut oleh Apple "Some of the glyphs") - tidak mungkin untuk mendapatkan ukuran aktual aktual yang diperlukan untuk menampilkan teks!Saya telah mengganti spasi di string saya dengan surat dan segera mendapatkan hasil yang benar.
Apple mengatakan di sini: https://developer.apple.com/documentation/foundation/nsstring/1524729-boundingrectwithsize
"Metode ini mengembalikan batas sebenarnya dari mesin terbang dalam string. Beberapa mesin terbang (spasi, misalnya) diizinkan untuk tumpang tindih batasan tata letak yang ditentukan oleh ukuran yang dilewati, sehingga dalam beberapa kasus nilai lebar dari komponen ukuran dari yang dikembalikan
CGRect
dapat melebihi nilai lebar dari parameter ukuran. "Jadi perlu untuk menemukan beberapa cara lain untuk menghitung ...
Setelah solusi proses penyelidikan yang lama akhirnya ditemukan !!! Saya tidak yakin ini akan bekerja dengan baik untuk semua kasus yang terkait
UITextView
, tetapi hal utama dan penting terdeteksi!boundingRectWithSize
fungsi sertaCTFramesetterSuggestFrameSizeWithConstraints
(dan banyak metode lain) akan menghitung ukuran dan porsi teks yang benar ketika persegi panjang yang benar digunakan. Sebagai contoh -UITextView
memilikitextView.bounds.size.width
- dan nilai ini bukan persegi panjang sebenarnya yang digunakan oleh sistem ketika teks menggambarUITextView
.Saya menemukan parameter yang sangat menarik dan melakukan perhitungan sederhana dalam kode:
Dan sulap - semua teks saya dihitung benar sekarang! Nikmati!
sumber
Cepat versi empat
Mengukur teks dengan CTFramesetter berfungsi paling baik karena memberikan ukuran integer dan menangani emoji dan karakter unicode lainnya dengan baik.
sumber
Saya tidak beruntung dengan semua saran ini. Tali saya berisi poin-poin unicode dan saya curiga mereka menyebabkan kesedihan dalam perhitungan. Saya perhatikan UITextView menangani gambar dengan baik, jadi saya melihat itu untuk meningkatkan perhitungannya. Saya melakukan hal berikut, yang mungkin tidak seoptimal metode menggambar NSString, tetapi setidaknya itu akurat. Ini juga sedikit lebih optimal daripada menginisialisasi UITextView hanya untuk menelepon
-sizeThatFits:
.sumber
Jika Anda ingin mendapatkan kotak berlari dengan memotong ekornya, pertanyaan ini dapat membantu Anda.
sumber
Ternyata SETIAP bagian dari NSAttributedString harus memiliki set kamus dengan setidaknya NSFontAttributeName dan set NSForegroundColorAttributeName, jika Anda ingin boundRectWithSize untuk benar-benar berfungsi!
Saya tidak melihat itu didokumentasikan di mana pun.
sumber
@warrenm Maaf untuk mengatakan bahwa metode framesetter tidak bekerja untuk saya.
Saya mendapatkan ini. Fungsi ini dapat membantu kita menentukan ukuran bingkai yang dibutuhkan untuk rentang string NSAttributedString di iphone / Ipad SDK untuk Lebar yang diberikan:
Ini dapat digunakan untuk ketinggian dinamis Sel UITableView
Terima kasih kepada HADDAD ISSA >>> http://haddadissa.blogspot.in/2010/09/compute-needed-heigh-for-fixed-width-of.html
sumber
#import <CoreText/CoreText.h>
Saya telah menemukan bahwa solusi yang disukai tidak menangani jeda baris.
Saya menemukan bahwa pendekatan ini berfungsi dalam semua kasus:
sumber
Saya memiliki masalah yang sama dengan tidak mendapatkan ukuran yang akurat menggunakan teknik ini dan saya telah mengubah pendekatan saya untuk membuatnya bekerja.
Saya memiliki string yang dikaitkan panjang yang saya coba untuk masuk ke tampilan gulir sehingga ditampilkan dengan benar tanpa terpotong. Apa yang saya lakukan untuk membuat teks bekerja dengan andal adalah tidak mengatur ketinggian sama sekali sebagai kendala dan sebaliknya membiarkan ukuran intrinsik untuk mengambil alih. Sekarang teks ditampilkan dengan benar tanpa terpotong dan saya tidak perlu menghitung tinggi.
Saya kira jika saya memang perlu mendapatkan ketinggian dengan andal saya akan membuat tampilan yang tersembunyi dan kendala ini dan mendapatkan ketinggian bingkai setelah kendala diterapkan.
sumber
Saya sedikit terlambat dalam permainan - tetapi saya telah mencoba mencari cara yang berfungsi untuk menemukan kotak pembatas yang akan cocok dengan string yang dikaitkan untuk membuat cincin fokus seperti mengedit file di Finder. semua yang saya coba gagal ketika ada spasi di akhir string atau beberapa spasi di dalam string.
boundingRectWithSize
gagal total untuk ini jugaCTFramesetterCreateWithAttributedString
.Menggunakan
NSLayoutManager
kode berikut tampaknya melakukan trik dalam semua kasus yang saya temukan sejauh ini dan mengembalikan sebuah kotak yang sempurna mengikat string. Bonus: jika Anda memilih teks, ujung seleksi langsung ke batas rect yang dikembalikan. Kode di bawah ini menggunakan layoutManager dari aNSTextView
.sumber
Bekerja pada semua font dengan sempurna!
sumber
Saya memiliki masalah yang sama, tetapi saya menyadari bahwa ketinggian dibatasi telah ditetapkan dengan benar. Jadi saya melakukan yang berikut:
sumber
Saya mencoba semuanya pada halaman ini dan masih memiliki satu case untuk UILabel yang tidak diformat dengan benar. Sebenarnya pengaturan attributedText pada label akhirnya memperbaiki masalahnya.
sumber
Satu hal yang saya perhatikan adalah bahwa persegi yang akan kembali
(CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(NSDictionary *)attributes context:(NSStringDrawingContext *)context
akan memiliki lebar lebih besar dari apa yang saya lewati. Ketika ini terjadi, tali saya akan terpotong. Saya mengatasinya seperti ini:Untuk lebih banyak konteks; Saya memiliki teks multi-baris dan saya mencoba untuk menemukan ketinggian yang tepat untuk menampilkannya. akan terpotong. Dari pengujian ketika boundingRectWithSize menggunakan lebar yang salah jumlah itu akan membuat ketinggian pendek adalah 1 baris. Jadi saya akan memeriksa apakah lebarnya lebih besar dan jika demikian tambahkan font's lineHeight untuk menyediakan ruang yang cukup untuk menghindari pemotongan.
sumber
jika bingkai label tidak menambahkan 10 metode ini tidak akan pernah berhasil! Semoga ini bisa membantu Anda! keberuntungan goog.
sumber
}
sumber
Saya ingin menambahkan pemikiran saya karena saya memiliki masalah yang sama persis.
Saya menggunakan
UITextView
karena memiliki perataan teks yang lebih bagus (membenarkan, yang pada saat itu tidak tersediaUILabel
), tetapi untuk "mensimulasikan" non-interaktif-non-digulirUILabel
, saya akan mematikan sepenuhnya menggulir, memantul, dan interaksi pengguna .Tentu saja, masalahnya adalah teks itu dinamis, dan sementara lebar akan diperbaiki, tinggi harus dihitung ulang setiap kali saya menetapkan nilai teks baru.
boundingRectWithSize
Sama sekali tidak bekerja dengan baik bagi saya, dari apa yang bisa saya lihat,UITextView
menambahkan beberapa margin di atas yangboundingRectWithSize
tidak akan masuk hitungan, oleh karena itu, ketinggian yang diperolehboundingRectWithSize
lebih kecil dari yang seharusnya.Karena teks tidak diperbarui dengan cepat, itu hanya digunakan untuk beberapa informasi yang paling sering diperbarui setiap 2-3 detik, saya telah memutuskan pendekatan berikut:
* Kode di atas tidak langsung disalin dari sumber saya, saya harus menyesuaikan / menghapusnya dari banyak hal lain yang tidak diperlukan untuk artikel ini. Jangan bawa untuk copy-paste-dan-itu-akan-bekerja-kode.
Kerugian yang jelas adalah bahwa ia telah mengalokasikan dan melepaskan, untuk setiap panggilan.
Tetapi, keuntungannya adalah Anda menghindari tergantung pada kompatibilitas antara bagaimana boundingRectWithSize menggambar teks dan menghitung ukuran serta implementasi menggambar teks di dalamnya
UITextView
(atauUILabel
yang juga dapat Anda gunakan hanya gantiUITextView
denganUILabel
). "Bug" apa pun yang dimiliki Apple dapat dihindari.PS Tampaknya Anda tidak perlu "temp" ini
UITextView
dan bisasizeThatFits
langsung bertanya dari target, tetapi itu tidak berhasil untuk saya. Meskipun logika akan mengatakan itu harus bekerja dan mengalokasikan / melepaskan sementaraUITextView
tidak diperlukan, itu tidak. Tetapi solusi ini bekerja dengan sempurna untuk teks apa pun yang akan saya atur.sumber
Ok jadi saya menghabiskan banyak waktu men-debug ini. Saya menemukan bahwa ketinggian teks maksimum yang ditentukan oleh
boundingRectWithSize
diizinkan untuk menampilkan teks oleh sayaUITextView
lebih rendah dari ukuran bingkai.Dalam kasus saya, frame paling banyak 140pt tetapi UITextView mentolerir teks paling banyak 131pt.
Saya harus mencari tahu secara manual dan hardcode ketinggian maksimum "nyata".
Ini solusinya:
sumber