Tizim qanday qilib tegishni qaysi ko'rinishga tushganligini aniqlaydi?
sobes.tech AI
AIdan javob
Sistem ikki asosiy mexanizmni ishlatadi: hit-test (teginish test) va ko‘rinishlar hierarxiyasi.
-
Hit-test: UIKit frameworki
hitTest(_:with:)metodidan foydalanadi, bu metod oynaning asosiy ko‘rinishi (UIWindow) ostidagi qaysi ko‘rinish teginish nuqtasining ostida ekanligini aniqlash uchun. Bu metod rekursiv tarzda ko‘rinishlar hierarxiyasini yuradi, boshlang‘ich sifatida asosiy. -
Ko‘rinishlar hierarxiyasi:
hitTest(_:with:)avvalo, nuqtaning hozirgi ko‘rinish chegaralarida joylashganligini tekshiradi. Agar joylashmagan bo‘lsa,nilqaytaradi.- Agar nuqta chegaralar ichida bo‘lsa, metod bolalar ko‘rinishlarini teskari tartibda (so‘nggi qo‘shilganidan birinchi qo‘shilganigacha) tekshiradi. Har bir bolaga, uning
hitTest(_:with:)metodini, ayni nuqtada chaqiradi (nuqtani bolaning koordinatlariga o‘tkazib). hitTest(_:with:)metodidannilbo‘lmagan natija olinsa (ya’ni, u yoki uning bolalaridan biri nuqtani o‘z ichiga olsa), bu "teginilgan" deb hisoblanadi va natija yuqoriga qaytariladi.- Agar hech qanday bola nuqtani o‘z ichiga olmasa va hozirgi ko‘rinish nuqtani o‘z ichiga olsa va
userInteractionEnabledfalseemas bo‘lsa,selfqaytariladi. - Agar
userInteractionEnabledhozirgi ko‘rinishdafalsebo‘lsa, yokihiddentruebo‘lsa, yokialpha0.01 dan kichik bo‘lsa, metodnilqaytaradi, hatto nuqta chegaralar ichida bo‘lsa ham.
Jarayon, nuqtani o‘z ichiga oladigan eng pastki ko‘rinishni topguncha davom etadi. Bu ko‘rinish hit-test view yoki hit-test result bo‘lib, unga (yoki uning eng yaqin mos keladigan ajdodiga) voqea boshqaruvi (touchesBegan, touchesMoved va boshqalar) delegatsiya qilinadi.
Mana hitTest yoki point(inside:with:) metodlarini qanday qilib maxsus xulq uchun qayta yozish mumkin:
import UIKit
class CustomView: UIView {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
// Nuqtaning bu ko‘rinishda joylashganligini tekshirish.
if !self.point(inside: point, with: event) {
return nil
}
// Bolalar ko‘rinishlarini teskari tartibda tekshirish.
for subview in subviews.reversed() {
// Nuqtani bolaning koordinatlariga o‘tkazish.
let convertedPoint = subview.convert(point, from: self)
// Rekursiv tarzda hitTest chaqirish.
if let hitTestView = subview.hitTest(convertedPoint, with: event) {
// Agar bola yoki uning vorislari nuqtani o‘z ichiga olsa, natijani qaytar.
return hitTestView
}
}
// Agar hech qanday bola nuqtani qabul qilmasa,
// va hozirgi ko‘rinish interaktiv bo‘lsa va nuqtani o‘z ichiga olsa, self qaytariladi.
return self
}
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
// Asosiy implementatsiya nuqtaning chegaralar ichida va ko‘rinish interaktivligini tekshiradi.
// return super.point(inside: point, with: event)
// Maxsus shakllar yoki bo‘sh joylar uchun qayta yozilishi mumkin, masalan, tegish maydonini kengaytirish.
let extendedBounds = bounds.insetBy(dx: -20, dy: -20) // Har tomondan 20pts kengaytirish
return extendedBounds.contains(point)
}
}
point(inside:with:) metodi hitTest(_:with:) ichida chaqiriladi va nuqtaning ko‘rinish ichida joylashganligini tezda tekshirish uchun ishlatiladi, bolalar ko‘rinishlarini tekshirishdan oldin.
Natijada, hierarxiyada eng pastki va nuqtani o‘z ichiga oladigan, userInteractionEnabled true, hidden false va alpha 0.01 dan katta bo‘lgan ko‘rinish topiladi va u hit-test view sifatida tan olinadi.