Bagaimana saya bisa mendeteksi perubahan teks di TextField? Metode delegasi shouldChangeCharactersInRange
berfungsi untuk sesuatu, tetapi itu tidak memenuhi kebutuhan saya persis. Sejak sampai mengembalikan YA, teks textField tidak tersedia untuk metode pengamat lainnya.
misalnya dalam kode saya calculateAndUpdateTextFields
tidak mendapatkan teks yang diperbarui, pengguna telah mengetik.
Apakah cara mereka untuk mendapatkan sesuatu seperti textChanged
Java event handler.
- (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string
{
if (textField.tag == kTextFieldTagSubtotal
|| textField.tag == kTextFieldTagSubtotalDecimal
|| textField.tag == kTextFieldTagShipping
|| textField.tag == kTextFieldTagShippingDecimal)
{
[self calculateAndUpdateTextFields];
}
return YES;
}
Jawaban:
Dari cara yang tepat untuk melakukan perubahan teks uitextfield, panggil kembali :
Dalam Objective-C:
Dalam Swift:
Anda bisa menggunakan itu dan menempatkan calculAndUpdateTextFields sebagai milik Anda
selector
.sumber
NO
, yang logis, karena ketika Anda kembaliNO
dari metode ini, Anda pada dasarnya mengatakan teks di lapangan tidak boleh berubah.textField.text = "Some new value";
. Apakah ada cara pintar untuk menangkap ini?UITextFieldDelegate
bahwa sesuatu sepertifunc textField: UITextField, didChangeText text: String
akan dimasukkan, tetapi ... (memberi orang-orang di Apple tampilan yang kotor)Jawaban XenElement tepat.
Hal di atas dapat dilakukan dalam pembangun antarmuka juga dengan mengklik kanan pada UITextField dan menyeret acara pengiriman "Editing yang Diubah" ke unit subkelas Anda.
sumber
untuk mengatur pendengar acara:
untuk benar-benar mendengarkan:
sumber
Cepat:
Kemudian, terapkan fungsi panggilan balik:
sumber
Seperti yang dinyatakan di sini: Peristiwa perubahan teks UITextField , tampaknya pada iOS 6 (iOS 6.0 dan 6.1 dicentang) tidak mungkin untuk sepenuhnya mendeteksi perubahan
UITextField
objek hanya dengan mengamatiUITextFieldTextDidChangeNotification
.Tampaknya hanya perubahan itu yang dilakukan secara langsung oleh keyboard iOS bawaan yang dilacak sekarang. Ini berarti bahwa jika Anda mengubah
UITextField
objek Anda hanya dengan memanggil sesuatu seperti ini:,myUITextField.text = @"any_text"
Anda tidak akan diberitahu tentang perubahan sama sekali.Saya tidak tahu apakah ini bug atau memang dimaksudkan. Sepertinya bug karena saya belum menemukan penjelasan yang masuk akal dalam dokumentasi. Ini juga dinyatakan di sini: Acara perubahan teks UITextField .
"Solusi" saya untuk ini adalah mengirimkan pemberitahuan sendiri untuk setiap perubahan yang saya buat
UITextField
(jika perubahan itu dilakukan tanpa menggunakan keyboard iOS bawaan). Sesuatu seperti ini:Dengan cara ini Anda 100% yakin bahwa Anda akan menerima pemberitahuan yang sama ketika Anda mengubah
.text
propertiUITextField
objek Anda , baik ketika Anda memperbarui "secara manual" dalam kode Anda atau melalui keyboard iOS bawaan.Penting untuk mempertimbangkan bahwa, karena ini bukan perilaku yang terdokumentasi, pendekatan ini dapat menyebabkan 2 pemberitahuan diterima untuk perubahan yang sama pada
UITextField
objek Anda . Tergantung pada kebutuhan Anda (apa yang sebenarnya Anda lakukan saatUITextField.text
perubahan), ini bisa menjadi ketidaknyamanan bagi Anda.Pendekatan yang sedikit berbeda adalah memposting pemberitahuan khusus (ini, dengan nama khusus selain
UITextFieldTextDidChangeNotification
) jika Anda benar-benar perlu tahu apakah pemberitahuan itu milik Anda atau "buatan iOS".EDIT:
Saya baru saja menemukan pendekatan berbeda yang menurut saya bisa lebih baik:
Ini melibatkan fitur Key-Value Observing (KVO) dari Objective-C ( http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid / 10000177-BCICJDHA ).
Pada dasarnya, Anda mendaftarkan diri sebagai pengamat properti dan jika properti ini berubah, Anda akan diberi tahu tentangnya. "Prinsip" sangat mirip dengan cara
NSNotificationCenter
kerjanya, menjadi keuntungan utama bahwa pendekatan ini bekerja secara otomatis juga pada iOS 6 (tanpa tweak khusus seperti harus memposting pemberitahuan secara manual).Untuk
UITextField
skenario kami, ini berfungsi dengan baik jika Anda menambahkan kode ini, misalnya, AndaUIViewController
yang berisi bidang teks:Kredit untuk jawaban ini mengenai manajemen "konteks": https://stackoverflow.com/a/12097161/2078512
Catatan: Sepertinya saat Anda sedang dalam proses mengedit a
UITextField
dengan keyboard iOS bawaan, properti "teks" dari bidang teks tidak diperbarui dengan setiap huruf baru diketik / dihapus. Sebaliknya, objek bidang teks akan diperbarui "secara keseluruhan" setelah Anda mengundurkan diri status responden pertama dari bidang teks.sumber
Kami dapat dengan mudah mengonfigurasikannya dari
Storyboard
, CTRL seret@IBAction
dan ubah acara sebagai berikut:sumber
Di sini dalam versi cepat untuk hal yang sama.
Terima kasih
sumber
Saya menyelesaikan masalah yang mengubah perilaku shouldChangeChractersInRange. Jika Anda mengembalikan TIDAK, perubahan tidak akan diterapkan oleh iOS secara internal, sebagai gantinya Anda memiliki kesempatan untuk mengubahnya secara manual dan melakukan tindakan apa pun setelah perubahan.
sumber
Versi Swift diuji:
Parameter menjelaskan:
Kemudian tambahkan metode yang Anda buat di atas di
UIViewController
:sumber
Cepat 4
sumber
Untuk Swift 3.0:
menggunakan kelas seperti:
sumber
Versi Swift 3
Dan dapatkan perubahannya di sini
Semoga ini bisa membantu.
sumber
Anda harus menggunakan notifikasi untuk menyelesaikan masalah ini, karena metode lain akan mendengarkan kotak input bukan input sebenarnya, terutama ketika Anda menggunakan metode input Cina. Di viewDidload
kemudian
}
Akhirnya, Anda lari, akan dilakukan.
sumber
Swift 3.1:
sumber
Versi Swift 3:
Jangan lupa mengatur delegasi.
sumber
Dengan penutupan:
dan menggunakan
sumber
KVO TIDAK bekerja di iOS untuk kontrol: http://stackoverflow.com/a/6352525/1402846 https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/KVO.html
Karena Anda tahu tampilan teks yang ingin Anda tonton:
Melakukan hal ini:
Namun, berhati-hatilah dengan itu:
kemungkinan Anda hanya ingin menelepon sekali , jadi jangan panggil, misalnya,
layoutSubviews
cukup sulit untuk mengetahui kapan sebaiknya menyebutnya selama proses pemunculan Anda. Itu akan tergantung pada situasi Anda. Sayangnya tidak ada solusi standar dan terkunci
misalnya Anda biasanya pasti tidak bisa meneleponnya
init
tepat waktu, karena tentu sajawatchedTextView
mungkin belum ada.
Tidak ada pemberitahuan yang dipanggil saat teks diubah secara programatis .
Ini adalah gangguan besar, kuno, dan bodoh dalam rekayasa iOS.
Kontrol sama sekali tidak - akhir cerita - panggilan pemberitahuan ketika properti .text diubah secara pemrograman.
Ini sangat menyebalkan karena tentu saja - jelas - setiap aplikasi yang pernah dibuat menetapkan teks secara terprogram, seperti membersihkan bidang setelah posting pengguna, dll.
Anda harus subklas tampilan teks (atau kontrol serupa) seperti ini:
(Kiat - jangan lupa panggilan super harus datang sebelumnya ! Panggilan pos.)
Tidak ada solusi yang tersedia, kecuali, Anda memperbaiki kontrol dengan subclass seperti yang ditunjukkan di atas. Itulah satu - satunya solusi.
Perhatikan notifikasi itu
hasil dalam
dipanggil.
( Tidak
textViewDidChange
.)sumber
sumber
Satu hal adalah Anda mungkin memiliki beberapa UITextFields. Jadi, beri mereka tag dan kemudian Anda dapat mengaktifkan tag. Berikut cara mengatur pengamat di kelas apa saja.
sumber
Versi Swift 4
Menggunakan Key-Value Observing Beri tahu objek tentang perubahan pada properti objek lain.
sumber