Saya memiliki pandangan yang ditata sepenuhnya menggunakan tata letak otomatis secara terprogram. Saya memiliki UITextView di tengah tampilan dengan item di atas dan di bawahnya. Semuanya berfungsi dengan baik, tetapi saya ingin dapat memperluas UITextView saat teks ditambahkan. Ini harus mendorong semua yang ada di bawahnya saat mengembang.
Saya tahu bagaimana melakukan ini dengan cara "pegas dan struts", tetapi apakah ada cara tata letak otomatis untuk melakukan ini? Satu-satunya cara yang dapat saya pikirkan adalah dengan menghapus dan menambahkan kembali kendala setiap kali perlu tumbuh.
ios
uitextview
autolayout
nslayoutconstraint
tharris
sumber
sumber
Jawaban:
Tampilan yang mengandung UITextView akan ditetapkan ukurannya
setBounds
oleh AutoLayout. Jadi, inilah yang saya lakukan. Superview pada awalnya mengatur semua kendala lain sebagaimana mestinya, dan pada akhirnya saya menempatkan satu kendala khusus untuk ketinggian UITextView, dan saya menyimpannya dalam variabel instan.Dalam
setBounds
metode ini, saya kemudian mengubah nilai konstanta.sumber
textViewDidChange
ini akan menghemat kode subclassing dan menulis kerumitan ...textViewDidChange:
tidak akan dipanggil saat menambahkan teks ke UITextView secara terprogram.Ringkasan: Nonaktifkan pengguliran tampilan teks Anda, dan jangan membatasi ketinggiannya.
Untuk melakukan ini secara pemrograman, masukkan kode berikut
viewDidLoad
:Untuk melakukan ini di Interface Builder, pilih tampilan teks, hapus centang Scrolling Diaktifkan di Attributes Inspector, dan tambahkan kendala secara manual.
Catatan: Jika Anda memiliki tampilan lain di atas / di bawah tampilan teks Anda, pertimbangkan untuk menggunakan a
UIStackView
untuk mengatur semuanya.sumber
intrinsicContentSize
seperti ini- (CGSize)intrinsicContentSize { CGSize size = [super intrinsicContentSize]; if (self.text.length == 0) { size.height = UIViewNoIntrinsicMetric; } return size; }
. Katakan padaku apakah itu berhasil untukmu. Tidak mengujinya sendiri.Inilah solusi untuk orang yang lebih suka melakukan semuanya dengan tata letak otomatis:
Inspektur Ukuran:
Atur prioritas ketahanan kompresi konten menjadi 1000.
Turunkan prioritas ketinggian kendala dengan mengklik "Edit" di Kendala. Buat kurang dari 1000.
Inspektur Atribut:
sumber
UITextView tidak menyediakan intrinsicContentSize, jadi Anda perlu mensubklasifikasikan dan menyediakannya. Untuk membuatnya tumbuh secara otomatis, batalkan intrinsicContentSize di layoutSubviews. Jika Anda menggunakan selain dari contentInset default (yang saya tidak rekomendasikan), Anda mungkin perlu menyesuaikan perhitungan intrinsicContentSize.
sumber
setScrollEnabled:
untuk selalu mengaturnya untukNO
Anda akan mendapatkan loop tak terbatas untuk ukuran konten intrinsik yang terus tumbuh.[textView sizeToFit]
ditextViewDidChange:
callback delegasi untuk Auto Layout untuk tumbuh atau menyusut textview (dan menghitung ulang setiap bergantung kendala) setelah setiap keystroke.-(void)layoutSubviews
dan bungkus semua kode-(CGSize)intrinsicContentSize
denganversion >= 7.0f && version < 7.1f
+else return [super intrinsicContentSize];
Anda dapat melakukannya melalui storyboard, cukup nonaktifkan "Scrolling Enabled" :)
sumber
Saya menemukan itu tidak sepenuhnya tidak umum dalam situasi di mana Anda mungkin masih perlu isScrollEnabled disetel ke true untuk memungkinkan interaksi UI yang masuk akal. Kasus sederhana untuk ini adalah ketika Anda ingin mengizinkan tampilan teks yang diperluas secara otomatis tetapi masih membatasi ketinggian maksimumnya untuk sesuatu yang masuk akal dalam UITableView.
Berikut adalah subkelas dari UITextView yang saya buat yang memungkinkan ekspansi otomatis dengan tata letak otomatis tetapi Anda masih dapat membatasi ketinggian maksimum dan yang akan mengatur apakah tampilan dapat digulir tergantung pada ketinggian. Secara default tampilan akan berkembang tanpa batas jika Anda memiliki pengaturan kendala seperti itu.
Sebagai bonus ada dukungan untuk menyertakan teks placeholder mirip dengan UILabel.
sumber
Anda juga dapat melakukannya tanpa subklas
UITextView
. Lihat jawaban saya untuk Bagaimana saya mengukur ukuran UITextView untuk kontennya di iOS 7?Gunakan nilai ekspresi ini:
untuk memperbarui
constant
daritextView
ketinggian 'sUILayoutConstraint
.sumber
Suatu hal penting yang perlu diperhatikan:
Karena UITextView adalah subkelas dari UIScrollView, maka ia tunduk pada properti AdaptsScrollViewInsets dari UIViewController secara otomatis.
Jika Anda mengatur tata letak dan TextView adalah subview pertama dalam hierarki UIViewControllers, itu akan diubah isinyaInsets jika secara otomatisAdjustsScrollViewInsets benar kadang-kadang menyebabkan perilaku tak terduga dalam tata letak otomatis.
Jadi jika Anda mengalami masalah dengan tata letak otomatis dan tampilan teks, coba atur
automaticallyAdjustsScrollViewInsets = false
pada view controller atau pindahkan textView ke depan dalam hierarki.sumber
Ini komentar yang lebih penting
Kunci untuk memahami mengapa jawaban vitaminwater bekerja adalah tiga hal:
contentOffset
adalah :Untuk lebih lanjut lihat objc scrollview dan memahami scrollview
Menggabungkan ketiga bersama-sama Anda akan dengan mudah memahami bahwa Anda perlu mengizinkan contentSize intrinsik textView untuk bekerja bersama kendala AutoLayout dari textView untuk mendorong logika. Ini hampir seolah-olah Anda textView berfungsi seperti UILabel
Untuk mewujudkannya, Anda perlu menonaktifkan pengguliran yang pada dasarnya berarti ukuran scrollView, ukuran contentSize dan dalam hal menambahkan containerView, maka ukuran containerView akan sama. Ketika semuanya sama, Anda TIDAK perlu menggulir. Dan Anda akan melakukannya . Memiliki berarti Anda belum menggulir ke bawah. Bahkan 1 poin pun turun! Hasilnya, textView akan terbentang semua.
0
contentOffset
0
contentOffSet
Ini juga tidak bernilai apa pun yang berarti bahwa batas dan bingkai scrollView adalah sama. Jika Anda gulir ke bawah 5 poin maka contentOffset Anda akan menjadi , sedangkan Anda akan sama dengan
0
contentOffset
5
scrollView.bounds.origin.y - scrollView.frame.origin.y
5
sumber
Solusi Plug and Play - Xcode 9
AutoLayout seperti
UILabel
, dengan deteksi link yang , pemilihan teks , mengedit dan bergulir dariUITextView
.Secara otomatis menangani
Banyak jawaban ini yang membuat saya 90% di sana, tetapi tidak ada yang terbukti bodoh.
Masukkan
UITextView
subclass ini dan Anda baik-baik saja.sumber
jawaban vitaminwater bekerja untuk saya.
Jika teks tampilan teks Anda memantul ke atas dan ke bawah selama pengeditan, setelah pengaturan
[textView setScrollEnabled:NO];
, aturSize Inspector > Scroll View > Content Insets > Never
.Semoga ini bisa membantu.
sumber
Tempatkan UILabel tersembunyi di bawah tampilan teks Anda. Label baris = 0. Atur batasan UITextView menjadi sama dengan label UIL (centerX, centerY, lebar, tinggi). Bekerja bahkan jika Anda meninggalkan perilaku gulir dari textView.
sumber
BTW, saya membangun UITextView yang diperluas menggunakan subkelas dan mengesampingkan ukuran konten intrinsik. Saya menemukan bug di UITextView yang mungkin ingin Anda selidiki dalam implementasi Anda sendiri. Inilah masalahnya:
Tampilan teks yang meluas akan tumbuh turun untuk mengakomodasi teks yang tumbuh jika Anda mengetikkan satu huruf sekaligus. Tetapi jika Anda menempelkan banyak teks ke dalamnya, itu tidak akan tumbuh turun tetapi teks akan menggulir ke atas dan teks di atas tidak terlihat.
Solusinya: Override setBounds: di subclass Anda. Untuk beberapa alasan yang tidak diketahui, pasting menyebabkan nilai bounds.origin.y menjadi non-zee (33 dalam setiap kasus yang saya lihat). Jadi saya mengesampingkan setBounds: untuk selalu mengatur bounds.origin.y ke nol. Memperbaiki masalah.
sumber
Inilah solusi cepat:
Masalah ini dapat terjadi jika Anda menyetel properti clipsToBounds menjadi false dari tampilan teks Anda. Jika Anda hanya menghapusnya, masalahnya hilang.
sumber
sumber