Sistem toxunuşun hansı görünüşə aid olduğunu necə müəyyən edir?
sobes.tech Süni İntellekt
AI-dan cavab
Sistem iki əsas mexanizm istifadə edir: hit-test və view hierarxiyası.
-
Hit-test (Dəymə test): UIKit çərçivəsi
hitTest(_:with:)metodundan istifadə edir, bu metod pəncərə (UIWindow) kök view-inin altında hansı view-in olduğunu müəyyən etmək üçün. Bu metod rekursiv olaraq view hierarxiyasını yoxlayır, kök view-dən başlayaraq. -
View hierarxiyası:
hitTest(_:with:)metodu əvvəlcə yoxlayır ki, toxunma nöqtəsi cari view-in sərhədləri daxilindədir ya yox. Əgər yoxdursa,nilqaytarır.- Əgər daxilindədirsə, metod uşaqlarını tərsinə (son əlavə olunan ilk) yoxlayır. Hər bir uşaq üçün
hitTest(_:with:)metodu çağırılır, bu zaman eyni toxunma nöqtəsi istifadə olunur (uşağın koordinatlarına çevrilmiş). - Əgər uşaqlardan biri
hitTest(_:with:)metodundannilolmayan nəticə qaytarırsa, bu, həmin uşaq və ya onun altındakı view-in toxunma nöqtəsini ehtiva etdiyini göstərir və nəticə yuxarıya qaytarılır. - Əgər heç bir uşaq toxunma nöqtəsini ehtiva etmirsə, və cari view daxilindədirsə və
userInteractionEnabledtruedirsə, ondaselfqaytarılır. - Əgər cari view-in
userInteractionEnabledfalsevə yahiddentruevə yaalpha0.01-dən kiçikdirsə, metodnilqaytarır, hətta nöqtə daxilində olsa belə.
Proses aşağıya doğru davam edir, ən aşağı view tapılana qədər, və bu view hit-test view və ya hit-test result olur, və ona (və ya ən yaxın valideyninə) hadisənin idarə olunması üçün vəzifə verilir (touchesBegan, touchesMoved və s.).
Budur hitTest və ya point(inside:with:) metodlarının xüsusi davranış üçün necə yenidən yazıla biləcəyi:
import UIKit
class CustomView: UIView {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
// Yoxlayırıq, nöqtə bizim view daxilindədir ya yox.
if !self.point(inside: point, with: event) {
return nil
}
// Uşaqları tərsinə yoxlayırıq.
for subview in subviews.reversed() {
let convertedPoint = subview.convert(point, from: self)
if let hitTestView = subview.hitTest(convertedPoint, with: event) {
return hitTestView
}
}
return self
}
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
// Əsasən, nöqtənin view daxilində olub-olmadığını və interaktiv olub-olmadığını yoxlayır.
let extendedBounds = bounds.insetBy(dx: -20, dy: -20) // 20pts artır
return extendedBounds.contains(point)
}
}
point(inside:with:) metodu hitTest(_:with:) tərəfindən çağırılır və nöqtənin ümumiyyətlə view sahəsində olub-olmadığını yoxlamaq üçün istifadə olunur, uşaqları yoxlamadan əvvəl.
Nəticədə, ən aşağı interaktiv view tapılır ki, onun geometrisi nöqtəni ehtiva edir və userInteractionEnabled true, hidden false, və alpha 0.01-dən böyükdür, və ona hadisə idarəetməsi təyin edilir.