Saya mengirimkan aplikasi saya sedikit lebih dari seminggu yang lalu dan mendapat email penolakan yang ditakuti hari ini. Ini memberi tahu saya bahwa aplikasi saya tidak dapat diterima karena saya menggunakan API non-publik; khususnya, katanya,
API non-publik yang termasuk dalam aplikasi Anda adalah firstResponder.
Sekarang, panggilan API yang menyinggung sebenarnya adalah solusi yang saya temukan di sini di SO:
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
UIView *firstResponder = [keyWindow performSelector:@selector(firstResponder)];
Bagaimana cara mendapatkan responden pertama saat ini di layar? Saya mencari cara agar aplikasi saya tidak ditolak.
objective-c
cocoa-touch
first-responder
Justin Kredible
sumber
sumber
Jawaban:
Dalam salah satu aplikasi saya, saya sering ingin responden pertama mengundurkan diri jika pengguna mengetuk latar belakang. Untuk tujuan ini saya menulis kategori di UIView, yang saya panggil di UIWindow.
Berikut ini didasarkan pada itu dan harus mengembalikan responden pertama.
iOS 7+
Cepat:
Contoh penggunaan di Swift:
sumber
[self.view endEditing:YES]
?Jika tujuan akhir Anda hanyalah mengundurkan diri dari responden pertama, ini akan berhasil:
[self.view endEditing:YES]
sumber
Cara umum memanipulasi responden pertama adalah dengan menggunakan tindakan nil yang ditargetkan. Ini adalah cara mengirim pesan sewenang-wenang ke rantai responden (dimulai dengan responden pertama), dan melanjutkan ke rantai sampai seseorang menanggapi pesan (telah menerapkan metode yang cocok dengan pemilih).
Untuk kasus penolakan keyboard, ini adalah cara paling efektif yang akan berfungsi tidak peduli jendela atau tampilan mana yang menjadi responden pertama:
Ini harus lebih efektif daripada bahkan
[self.view.window endEditing:YES]
.(Terima kasih kepada BigZaphod untuk mengingatkan saya tentang konsep ini)
sumber
Berikut adalah kategori yang memungkinkan Anda untuk dengan cepat menemukan responden pertama dengan menelepon
[UIResponder currentFirstResponder]
. Cukup tambahkan dua file berikut ke proyek Anda:UIResponder + FirstResponder.h
UIResponder + FirstResponder.m
Kuncinya di sini adalah mengirimkan tindakan ke nol mengirimnya ke responden pertama.
(Saya awalnya menerbitkan jawaban ini di sini: https://stackoverflow.com/a/14135456/322427 )
sumber
Ini ekstensi yang diterapkan di Swift berdasarkan jawaban Jakob Egger yang paling bagus:
Cepat 4
sumber
current
bukanfirst
?Itu tidak cantik, tetapi cara saya mengundurkan diri responden pertama ketika saya tidak tahu apa itu responden:
Buat UITextField, baik dalam IB atau secara terprogram. Jadikan itu Tersembunyi. Tautkan ke kode Anda jika Anda membuatnya di IB.
Kemudian, ketika Anda ingin mengabaikan keyboard, Anda mengalihkan responden ke bidang teks yang tidak terlihat, dan segera mengundurkan diri:
sumber
Untuk versi Swift 3 & 4 dari nevyn's jawaban :
sumber
Berikut adalah solusi yang melaporkan responden pertama yang benar (misalnya, banyak solusi lain tidak akan melaporkan
UIViewController
sebagai responden pertama), tidak memerlukan pengulangan hierarki tampilan, dan tidak menggunakan API pribadi.Ini memanfaatkan metode Apple sendAction: to: from: forEvent:, yang sudah tahu cara mengakses responden pertama.
Kita hanya perlu men-tweak dengan 2 cara:
UIResponder
sehingga dapat mengeksekusi kode kita sendiri pada responden pertama.UIEvent
untuk mengembalikan responden pertama.Ini kodenya:
sumber
Responden pertama dapat berupa instance dari kelas UIResponder, jadi ada kelas lain yang mungkin menjadi responden pertama meskipun UIViews. Sebagai contoh
UIViewController
mungkin juga menjadi responden pertama.Dalam inti ini Anda akan menemukan cara rekursif untuk mendapatkan responden pertama dengan mengulangi hierarki pengontrol mulai dari rootViewController dari jendela aplikasi.
Anda dapat mengambil responden pertama dengan melakukan
Namun, jika responden pertama bukan subkelas dari UIView atau UIViewController, pendekatan ini akan gagal.
Untuk memperbaiki masalah ini, kita dapat melakukan pendekatan yang berbeda dengan membuat kategori
UIResponder
dan melakukan beberapa sihir swizzeling untuk dapat membangun array dari semua instance hidup dari kelas ini. Kemudian, untuk mendapatkan responden pertama kita dapat mengulangi dan menanyakan setiap objek apakah-isFirstResponder
.Pendekatan ini dapat ditemukan diimplementasikan dalam inti lain ini .
Semoga ini bisa membantu.
sumber
Menggunakan Swift dan dengan objek tertentu
UIView
ini mungkin membantu:Cukup letakkan di Anda
UIViewController
dan gunakan seperti ini:Perhatikan bahwa hasilnya adalah nilai Opsional sehingga nihil jika tidak ditemukan firstResponser di subview tampilan yang diberikan.
sumber
Iterate atas pandangan yang bisa menjadi responden pertama dan gunakan
- (BOOL)isFirstResponder
untuk menentukan apakah mereka saat ini.sumber
Peter Steinberger hanya tweet tentang pemberitahuan pribadi
UIWindowFirstResponderDidChangeNotification
, yang dapat Anda amati jika Anda ingin menonton perubahan responden pertama.sumber
Jika Anda hanya perlu mematikan keyboard ketika pengguna mengetuk area latar belakang mengapa tidak menambahkan pengenal isyarat dan menggunakannya untuk mengirim
[[self view] endEditing:YES]
pesan?Anda dapat menambahkan Tap recogniser gesture di file xib atau storyboard dan menghubungkannya ke suatu tindakan,
terlihat seperti ini kemudian selesai
sumber
Yang penting di sini adalah versi Swift dari pendekatan Jakob Egger yang mengagumkan:
sumber
Inilah yang saya lakukan untuk menemukan apa yang UITextField adalah responden pertama ketika pengguna mengklik Simpan / Batalkan dalam ModalViewController:
sumber
Inilah yang saya miliki di Kategori UIViewController saya. Berguna untuk banyak hal, termasuk mendapatkan responden pertama. Blok sangat bagus!
sumber
Dengan kategori aktif
UIResponder
, dimungkinkan untuk secara sah bertanyaUIApplication
objek untuk memberi tahu Anda siapa responden pertama.Lihat ini:
Apakah ada cara untuk meminta tampilan iOS yang anak-anaknya memiliki status responden pertama?
sumber
Anda dapat memilih
UIView
ekstensi berikut untuk mendapatkannya (kredit oleh Daniel) :sumber
Anda dapat mencoba juga seperti ini:
Saya tidak mencobanya tetapi sepertinya solusi yang bagus
sumber
Solusi dari romeo https://stackoverflow.com/a/2799675/661022 keren, tapi saya perhatikan bahwa kodenya perlu satu loop lagi. Saya bekerja dengan tableViewController. Saya mengedit skrip dan kemudian saya memeriksa. Semuanya bekerja dengan sempurna.
Saya merekomendasikan untuk mencoba ini:
sumber
if ([textField isKindOfClass:[UITextField class]])
, mengizinkan penggunaan untuk uitextview, dan dapat mengembalikan firstresponder.Ini adalah kandidat yang bagus untuk rekursi! Tidak perlu menambahkan kategori ke UIView.
Penggunaan (dari pengontrol tampilan Anda):
Kode:
sumber
Anda dapat memanggil api privite seperti ini, abaikan:
sumber
Versi cepat dari tanggapan @ thomas-müller
sumber
Saya memiliki pendekatan yang sedikit berbeda dari kebanyakan di sini. Daripada mengulangi kumpulan pandangan yang mencari yang telah
isFirstResponder
ditetapkan, saya juga mengirim pesannil
, tetapi saya menyimpan penerima (jika ada), lalu mengembalikan nilai itu sehingga penelepon mendapatkan contoh aktual (lagi, jika ada) .Saya kemudian dapat mengundurkan diri dari responden pertama, jika ada, dengan melakukan ini ...
Tapi sekarang saya juga bisa melakukan ini ...
sumber
Saya ingin berbagi dengan Anda implementasi saya untuk menemukan responden pertama di UIView. Saya harap ini membantu dan maaf untuk bahasa inggris saya. Terima kasih
sumber
Kode di bawah ini berfungsi.
sumber
Pembaruan: Saya salah. Anda memang dapat menggunakan
UIApplication.shared.sendAction(_:to:from:for:)
untuk memanggil responden pertama yang ditunjukkan dalam tautan ini: http://stackoverflow.com/a/14135456/746890 .Sebagian besar jawaban di sini tidak dapat benar-benar menemukan responden pertama saat ini jika tidak ada dalam hierarki tampilan. Misalnya,
AppDelegate
atauUIViewController
subclass.Ada cara untuk menjamin Anda menemukannya meskipun objek responden pertama bukan a
UIView
.Pertama mari kita terapkan versi yang dibalik darinya, menggunakan
next
properti dariUIResponder
:Dengan properti yang dihitung ini, kami dapat menemukan responden pertama saat ini dari bawah ke atas walaupun itu tidak
UIView
. Misalnya, dari aview
keUIViewController
siapa yang mengelolanya, jika pengontrol tampilan adalah responden pertama.Namun, kami masih membutuhkan resolusi top-down, satu
var
untuk mendapatkan responden pertama saat ini.Pertama dengan hierarki tampilan:
Ini akan mencari responden pertama mundur, dan jika tidak dapat menemukannya, ia akan memberi tahu subview untuk melakukan hal yang sama (karena subviewnya
next
tidak harus dengan sendirinya). Dengan ini kita dapat menemukannya dari tampilan apa pun, termasukUIWindow
.Dan akhirnya, kita dapat membangun ini:
Jadi ketika Anda ingin mengambil responden pertama, Anda dapat menghubungi:
sumber
Cara termudah untuk menemukan responden pertama:
Langkah berikutnya:
Penggunaan: Dapatkan
UIResponder.actualFirst
untuk tujuan Anda sendiri.sumber