Saya punya UITextView
di Aplikasi iOS saya, yang menampilkan sejumlah besar teks.
Saya kemudian paging teks ini dengan menggunakan parameter margin of the offset UITextView
.
Masalah saya adalah bahwa padding UITextView
membingungkan perhitungan saya karena tampaknya berbeda tergantung pada ukuran font dan jenis huruf yang saya gunakan.
Oleh karena itu, saya mengajukan pertanyaan: Apakah mungkin untuk menghapus lapisan di sekitar konten UITextView
?
Nantikan tanggapan Anda!
ios
iphone
cocoa-touch
uikit
uitextview
sniurkst
sumber
sumber
Jawaban:
Mutakhir untuk 2019
Ini adalah salah satu bug paling konyol di iOS.
Kelas yang diberikan di sini,
UITextViewFixed
biasanya merupakan solusi paling masuk akal secara keseluruhan.Ini kelasnya:
Jangan lupa untuk mematikan scrollEnabled di Inspektur!
Solusinya bekerja dengan baik di storyboard
Solusinya bekerja dengan baik saat runtime
Itu dia, sudah selesai.
Secara umum, itu harus menjadi semua yang Anda butuhkan dalam banyak kasus .
Bahkan jika Anda mengubah ketinggian tampilan teks dengan cepat ,
UITextViewFixed
biasanya melakukan semua yang Anda butuhkan.(Contoh umum mengubah ketinggian dengan cepat, mengubahnya sebagai tipe pengguna.)
Ini adalah UITextView dari Apple yang rusak ...
Ini adalah
UITextViewFixed
:Perhatikan bahwa tentu saja Anda harus
matikan scrollEnabled di Inspektur!
Jangan lupa mematikan scrollEnabled! :)
Beberapa masalah lebih lanjut
(1) Dalam beberapa kasus yang tidak biasa - misalnya, beberapa kasus tabel dengan fleksibel, ketinggian sel yang berubah secara dinamis - Apple melakukan hal yang aneh: Mereka menambah ruang ekstra di bagian bawah . Tidak benar-benar! Ini harus menjadi salah satu hal yang paling menyebalkan di iOS.
Ini adalah "perbaikan cepat" untuk menambahkan hal-hal di atas yang biasanya membantu kegilaan itu.
(2) Kadang-kadang, untuk memperbaiki kekacauan Apple yang lain, Anda harus menambahkan ini:
(3) Dapat diperdebatkan, kita harus menambahkan:
setelah
.lineFragmentPadding = 0
diUITextViewFixed
.Namun ... percaya atau tidak ... itu tidak berfungsi di iOS saat ini! (Dicentang pada 2019.) Mungkin perlu menambahkan baris itu di masa mendatang.
Fakta yang
UITextView
rusak di iOS adalah salah satu hal paling aneh di semua komputasi mobile. Sepuluh tahun ulang tahun pertanyaan ini dan masih belum diperbaiki!Akhirnya, inilah tip yang agak mirip untuk Bidang Teks : https://stackoverflow.com/a/43099816/294884
Tip yang sepenuhnya acak: bagaimana cara menambahkan "..." di bagian akhir
Seringkali Anda menggunakan UITextView "like a UILabel". Jadi Anda ingin memotong teks menggunakan elipsis "..."
Jika demikian, tambahkan baris kode ketiga di "pengaturan":
Tip berguna jika Anda ingin tinggi nol, padahal tidak ada teks sama sekali
Seringkali Anda menggunakan tampilan teks untuk hanya menampilkan teks. Jadi, pengguna tidak dapat mengedit apa pun. Anda menggunakan baris "0" yang berarti tampilan teks akan secara otomatis mengubah ketinggian tergantung pada berapa banyak baris teks.
Itu bagus, tetapi jika tidak ada teks sama sekali maka sayangnya Anda mendapatkan ketinggian yang sama seperti jika ada satu baris teks !! Tampilan teks tidak pernah "hilang".
Jika Anda ingin "pergi", tambahkan saja ini
(Saya membuatnya '1' jadi jelas apa yang terjadi, '0' baik-baik saja.)
Bagaimana dengan UILabel?
Saat hanya menampilkan teks, UILabel memiliki banyak keunggulan dibandingkan UITextView. UILabel tidak mengalami masalah yang dijelaskan pada halaman QA ini. Memang alasan kita semua biasanya "menyerah" dan hanya menggunakan UITextView adalah bahwa UILabel sulit untuk dikerjakan. Khususnya sangat sulit untuk hanya menambahkan padding , dengan benar, ke UILabel. Sebenarnya di sini adalah diskusi lengkap tentang bagaimana "akhirnya" menambahkan padding dengan benar ke UILabel: https://stackoverflow.com/a/58876988/294884 Dalam beberapa kasus jika Anda melakukan tata letak yang sulit dengan sel ketinggian dinamis, kadang-kadang lebih baik melakukannya dengan cara yang sulit dengan UILabel.
sumber
self.textView.isScrollEnabled = false
di dalamviewDidLayoutSubviews()
dan itu berhasil juga. Apple hanya suka membuat kita melompat melalui lingkaran :)translatesAutoresizingMaskIntoConstraints
. Dengan jawaban ini saja saya tidak dapat menghapus semua margin (beberapa margin bawah aneh menolak untuk pergi) dalam hierarki tampilan menggunakan tata letak otomatis. Ini juga berkaitan dengan perhitungan ukuran tampilan menggunakansystemLayoutSizeFitting
, yang sebelumnya mengembalikan ukuran tidak valid karena keretaUITextView
Untuk iOS 7.0, saya telah menemukan bahwa trik contentInset tidak lagi berfungsi. Ini adalah kode yang saya gunakan untuk menghilangkan margin / padding di iOS 7.
Ini membawa tepi kiri teks ke tepi kiri wadah:
Ini menyebabkan bagian atas teks sejajar dengan bagian atas wadah
Kedua Lines diperlukan untuk menghapus margin / padding sepenuhnya.
sumber
self.descriptionTextView.textContainerInset = UIEdgeInsetsZero;
lineFragmentPadding
ke 0 adalah keajaiban yang saya cari. Saya tidak tahu mengapa Apple membuatnya sangat sulit untuk mengatur konten UITextView dengan kontrol lain.lineFragmentPadding
tidak dimaksudkan untuk memodifikasi margin. Dari dokumen Line fragment padding tidak dirancang untuk mengekspresikan margin teks. Sebagai gantinya, Anda harus menggunakan insets pada tampilan teks Anda, menyesuaikan atribut margin paragraf, atau mengubah posisi tampilan teks dalam superview-nya.Solusi ini ditulis pada tahun 2009 ketika IOS 3.0 dirilis. Itu tidak berlaku lagi.
Saya mengalami masalah yang sama persis, pada akhirnya saya harus menggunakan
dimana nameField adalah a
UITextView
. Font yang kebetulan saya gunakan adalah Helvetica 16 point. Ini hanya solusi khusus untuk ukuran bidang tertentu yang saya gambar. Ini membuat offset kiri rata dengan sisi kiri, dan offset atas di mana saya inginkan untuk kotaknya.Selain itu, ini sepertinya hanya berlaku untuk
UITextViews
tempat Anda menggunakan aligment default, yaitu.Menyelaraskan ke kanan misalnya dan
UIEdgeInsetsMake
tampaknya tidak berdampak sama sekali di tepi kanan.Paling tidak, menggunakan properti .contentInset memungkinkan Anda untuk menempatkan bidang Anda dengan posisi "benar", dan mengakomodasi penyimpangan tanpa mengimbangi Anda
UITextViews
.sumber
Membangun dari beberapa jawaban bagus yang sudah diberikan, berikut ini adalah murni solusi berbasis Storyboard / Interface Builder yang bekerja di iOS 7.0+
Atur Atribut Runtime yang Ditentukan Pengguna UITextView untuk kunci berikut:
sumber
Di iOS 5
UIEdgeInsetsMake(-8,-8,-8,-8);
sepertinya bekerja dengan baik.sumber
Saya pasti akan menghindari jawaban yang melibatkan nilai-nilai kode-keras, karena margin yang sebenarnya dapat berubah dengan pengaturan ukuran font pengguna, dll.
Inilah jawaban @ user1687195, ditulis tanpa mengubah
textContainer.lineFragmentPadding
(karena dokumen menyatakan ini bukan penggunaan yang dimaksudkan).Ini berfungsi baik untuk iOS 7 dan yang lebih baru.
Ini secara efektif hasil yang sama, hanya sedikit lebih bersih karena tidak menyalahgunakan properti lineFragmentPadding.
sumber
self.textView.textContainer.lineFragmentPadding = 0;
lineFragmentPadding
tidak dimaksudkan untuk mengontrol margin. Itu sebabnya Anda seharusnya menggunakannyatextContainerInset
.Solusi Storyboard atau Pembangun Antarmuka menggunakan Atribut Runtime yang Ditentukan Pengguna :
Tangkapan layar adalah dari iOS 7.1 & iOS 6.1 dengan
contentInset = {{-10, -5}, {0, 0}}
.sumber
Semua jawaban ini membahas pertanyaan judul, tetapi saya ingin mengusulkan beberapa solusi untuk masalah yang disajikan dalam tubuh pertanyaan OP.
Ukuran Konten Teks
Cara cepat untuk menghitung ukuran teks di dalamnya
UITextView
adalah dengan menggunakanNSLayoutManager
:Ini memberikan total konten yang dapat digulir, yang mungkin lebih besar dari
UITextView
bingkai. Saya menemukan ini jauh lebih akurat daripadatextView.contentSize
karena itu benar-benar menghitung berapa banyak ruang teks. Misalnya, diberi yang kosongUITextView
:Tinggi garis
UIFont
memiliki properti yang dengan cepat memungkinkan Anda untuk mendapatkan ketinggian garis untuk font yang diberikan. Sehingga Anda dapat dengan cepat menemukan ketinggian baris teks di AndaUITextView
dengan:Menghitung Ukuran Teks yang Terlihat
Menentukan jumlah teks yang benar-benar terlihat penting untuk menangani efek "paging".
UITextView
memiliki properti yang disebuttextContainerInset
yang sebenarnya merupakan margin antara aktualUITextView.frame
dan teks itu sendiri. Untuk menghitung ketinggian sebenarnya dari bingkai yang terlihat, Anda dapat melakukan perhitungan berikut:Menentukan Ukuran Paging
Terakhir, sekarang setelah Anda memiliki ukuran teks dan konten yang terlihat, Anda dapat dengan cepat menentukan apa yang seharusnya menjadi offset Anda dengan mengurangi
textHeight
daritextSize
:Dengan menggunakan semua metode ini, saya tidak menyentuh insets saya dan saya dapat pergi ke tanda sisipan atau di mana pun dalam teks yang saya inginkan.
sumber
Anda dapat menggunakan
textContainerInset
properti dariUITextView
:textView.textContainerInset = UIEdgeInsetsMake (10, 10, 10, 10);
(atas, kiri, bawah, kanan)
sumber
textContainerInset
properti tidak berfungsi untuk saya ketika saya ingin mengubahnya ke nilai baru — lihat stackoverflow.com/questions/19422578/… .Untuk iOS 10, baris berikut berfungsi untuk menghapus lapisan atas dan bawah.
sumber
UIEdgeInset.zero
bekerja menggunakan XCode 8.3 dan iOS 10.3 SimulatorSwift terbaru:
sumber
Ini adalah versi terbaru dari jawaban Fattie yang sangat membantu. Itu menambahkan 2 baris penting yang membantu saya membuat tata letak berfungsi pada iOS 10 dan 11 (dan mungkin juga pada yang lebih rendah):
Garis yang penting adalah dua
translatesAutoresizingMaskIntoConstraints = <true/false>
pernyataan!Ini secara mengejutkan menghapus semua margin dalam semua keadaan saya!
Meskipun
textView
bukan responden pertama, bisa saja terjadi bahwa ada beberapa margin bawah yang aneh yang tidak dapat diselesaikan dengan menggunakansizeThatFits
metode yang disebutkan dalam jawaban yang diterima.Ketika mengetuk textView tiba-tiba margin bawah aneh menghilang dan semuanya tampak seperti seharusnya, tetapi hanya segera setelah textView didapat
firstResponder
.Jadi saya baca di sini di SO bahwa mengaktifkan dan menonaktifkan
translatesAutoresizingMaskIntoConstraints
tidak membantu ketika mengatur frame / batas secara manual di antara panggilan.Untungnya ini tidak hanya bekerja dengan pengaturan bingkai tetapi dengan 2 garis
setup()
terjepit di antara duatranslatesAutoresizingMaskIntoConstraints
panggilan!Ini misalnya sangat membantu ketika menghitung bingkai tampilan menggunakan
systemLayoutSizeFitting
pada aUIView
. Memberikan ukuran yang benar (yang sebelumnya tidak)!Seperti dalam jawaban asli yang disebutkan:
Jangan lupa mematikan scrollEnabled di Inspektur!
Solusi itu tidak berfungsi dengan baik di storyboard, serta saat runtime.
Itu saja, sekarang Anda benar-benar selesai!
sumber
Untuk swift 4, Xcode 9
Gunakan fungsi berikut ini dapat mengubah margin / padding teks di UITextView
jadi dalam hal ini adalah
sumber
Melakukan solusi inset saya masih memiliki bantalan di sisi kanan dan bawah. Penyelarasan teks juga menyebabkan masalah. Satu-satunya cara pasti yang saya temukan adalah menempatkan tampilan teks di dalam tampilan lain yang terpotong menjadi batas.
sumber
Berikut ini adalah sedikit ekstensi mudah yang akan menghapus margin default Apple dari setiap tampilan teks di aplikasi Anda.
Catatan: Pembuat Antarmuka masih akan menunjukkan margin lama, tetapi aplikasi Anda akan berfungsi seperti yang diharapkan.
sumber
Bagi saya (iOS 11 & Xcode 9.4.1) yang berfungsi secara ajaib adalah mengatur properti textView.font sesuai
UIFont.preferred(forTextStyle:UIFontTextStyle)
gaya dan juga jawaban pertama yang disebutkan oleh @Fattie. Tapi jawaban @Fattie tidak berfungsi sampai saya mengatur properti textView.font yang lain UITextView terus bersikap tidak menentu.sumber
Jika ada orang yang mencari versi Swift terbaru maka kode di bawah ini berfungsi dengan baik dengan Xcode 10.2 dan Swift 4.2
sumber
Saya telah menemukan satu pendekatan lagi, mendapatkan tampilan dengan teks dari subview UITextView dan mengaturnya dalam metode layoutSubview dari subclass:
sumber
Pengguliran textView juga mempengaruhi posisi teks dan membuatnya tampak seperti tidak terpusat secara vertikal. Saya berhasil memusatkan teks dalam tampilan dengan menonaktifkan gulir dan mengatur inset atas ke 0:
Untuk beberapa alasan saya belum mengetahuinya, kursor masih belum terpusat sebelum pengetikan dimulai, tetapi pusat teks segera saat saya mulai mengetik.
sumber
Jika Anda ingin mengatur string HTML dan menghindari bantalan bawah, pastikan Anda tidak menggunakan tag blok yaitu div, hal.
Dalam kasus saya ini adalah alasannya. Anda dapat dengan mudah mengujinya dengan mengganti kemunculan tag blok dengan tag span.
sumber
Untuk SwiftUI
Jika Anda membuat TextView sendiri menggunakan
UIViewRepresentable
dan ingin mengontrol padding, dalammakeUIView
fungsi Anda , cukup lakukan:uiTextView.textContainerInset = UIEdgeInsets(top: 10, left: 18, bottom: 0, right: 18)
atau apapun yang kamu mau.
sumber
sumber