Sementara sebagian besar dokumen apel ditulis dengan sangat baik, saya pikir ' Panduan Penanganan Acara untuk iOS ' merupakan pengecualian. Sulit bagi saya untuk memahami dengan jelas apa yang telah dijelaskan di sana.
Dokumen itu mengatakan,
Dalam pengujian hit, jendela memanggil
hitTest:withEvent:
tampilan hierarki tampilan paling atas; metode ini dilanjutkan dengan secara rekursif memanggilpointInside:withEvent:
setiap tampilan dalam hierarki tampilan yang mengembalikan YA, melanjutkan hierarki hingga menemukan subview di mana batas-batasnya terjadi. Pandangan itu menjadi tampilan uji coba.
Jadi, apakah hanya hitTest:withEvent:
tampilan paling atas yang dipanggil oleh sistem, yang memanggil pointInside:withEvent:
semua subview, dan jika pengembalian dari subview tertentu adalah YA, maka panggilan pointInside:withEvent:
subclass subview itu?
Jawaban:
Sepertinya pertanyaan yang cukup mendasar. Tapi saya setuju dengan Anda dokumennya tidak sejelas dokumen lainnya, jadi inilah jawaban saya.
Implementasi
hitTest:withEvent:
di UIResponder melakukan hal berikut:pointInside:withEvent:
dariself
hitTest:withEvent:
pengembaliannil
. akhir dari cerita.hitTest:withEvent:
pesan ke subview-nya. dimulai dari subview tingkat atas, dan berlanjut ke tampilan lain hingga subview mengembalikan non-nil
objek, atau semua subview menerima pesan.nil
objek di pertama kalinya, yang pertamahitTest:withEvent:
mengembalikan objek itu. akhir dari cerita.nil
objek, yang pertamahitTest:withEvent:
mengembalikanself
Proses ini berulang secara berulang, jadi biasanya tampilan daun hierarki tampilan dikembalikan pada akhirnya.
Namun, Anda mungkin mengganti
hitTest:withEvent
untuk melakukan sesuatu yang berbeda. Dalam banyak kasus, mengesampingkanpointInside:withEvent:
lebih sederhana dan masih menyediakan opsi yang cukup untuk mengubah penanganan acara di aplikasi Anda.sumber
hitTest:withEvent:
dari semua subview akhirnya dijalankan?hitTest:withEvent:
dalam tampilan Anda (danpointInside
jika Anda mau), cetak log dan panggil[super hitTest...
untuk mencari tahu siapahitTest:withEvent:
yang dipanggil dalam urutan mana.Saya pikir Anda membingungkan subkelas dengan hierarki tampilan. Apa yang dikatakan dokter adalah sebagai berikut. Katakanlah Anda memiliki hierarki tampilan ini. Menurut hierarki, saya tidak berbicara tentang hierarki kelas, tetapi pandangan dalam hierarki tampilan, sebagai berikut:
Katakanlah Anda memasukkan jari Anda ke dalam
D
. Inilah yang akan terjadi:hitTest:withEvent:
dipanggilA
, tampilan paling atas dari hierarki tampilan.pointInside:withEvent:
disebut secara rekursif pada setiap tampilan.pointInside:withEvent:
dipanggilA
, dan kembaliYES
pointInside:withEvent:
dipanggilB
, dan kembaliNO
pointInside:withEvent:
dipanggilC
, dan kembaliYES
pointInside:withEvent:
dipanggilD
, dan kembaliYES
YES
, itu akan melihat hierarki untuk melihat subview di mana sentuhan itu terjadi. Dalam hal ini, dariA
,C
danD
, itu akan terjadiD
.D
akan menjadi tampilan uji cobasumber
hitTest:withEvent:
tentang B, C dan D juga dipanggil. Apa yang terjadi jika D adalah subview dari C, bukan A? Saya pikir saya bingung ...A
kembaliYES
juga, sama sepertiC
danD
tidak?Saya menemukan Hit-Testing ini di iOS sangat membantu
Edit Swift 4:
sumber
Terima kasih atas jawaban, mereka membantu saya untuk menyelesaikan situasi dengan pandangan "overlay".
Asumsikan
X
- sentuhan pengguna.pointInside:withEvent:
padaB
pengembalianNO
, jadihitTest:withEvent:
kembaliA
. Aku menulis kategori padaUIView
isu pegangan ketika Anda harus menerima sentuhan di atas yang paling terlihat pandangan.userInteractionEnabled
set keNO
;self
,self
akan dianggap sebagai hasil yang potensial.Catatan,
[self.subviewsreverseObjectEnumerator]
diperlukan untuk mengikuti hierarki tampilan dari paling atas ke bawah. Dan periksa untukclipsToBounds
memastikan tidak menguji subview bertopeng.Pemakaian:
hitTest:withEvent:
dengan iniOfficial Apple's Guide juga memberikan beberapa ilustrasi yang bagus.
Semoga ini bisa membantu seseorang.
sumber
Itu menunjukkan seperti cuplikan ini!
sumber
Potongan @lion bekerja seperti pesona. Saya porting ke swift 2.1 dan menggunakannya sebagai ekstensi untuk UIView. Saya mempostingnya di sini kalau-kalau ada yang membutuhkannya.
Untuk menggunakannya, cukup ganti hitTest: point: withEvent di uiview Anda sebagai berikut:
sumber
Diagram kelas
Hit Testing
Menemukan sebuah
First Responder
First Responder
dalam hal ini adalahUIView
point()
metode terdalam yang mengembalikan trueSecara internal
hitTest()
terlihat sepertiKirim Sentuh Acara ke
First Responder
Mari kita lihat contohnya
Rantai Penanggap
Lihatlah contohnya
[Android onTouch]
sumber