Sobes.tech
Middle

Jak można określić, czy użytkownik kliknął na warstwę (layer)?

sobes.tech AI

Odpowiedź od AI

Możesz użyć testu trafienia: określić, na którym dokładnie poziomie nastąpiło dotknięcie. Core Animation udostępnia do tego dwie metody:

  1. hitTest(_:):

    • Sprawdza, czy punkt znajduje się w granicach poziomu lub któregoś z jego podpoziomów.
    • Zwraca najgłębszy podpoziom (lub sam poziom), który zawiera punkt.
    • Uwzględnia isHidden = true.
  2. contains(_:):

    • Sprawdza tylko, czy punkt znajduje się w granicach samego poziomu.
    • Nie bierze pod uwagę hierarchii podpoziomów.
    • Nie uwzględnia isHidden.

Zazwyczaj używa się hitTest, ponieważ jest bardziej precyzyjne w określaniu interaktywności.

Przykład użycia hitTest w obsłudze dotknięć:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let touch = touches.first else { return }

    let locationInView = touch.location(in: view)

    // Konwersja punktu z koordynatów widoku do koordynatów poziomu
    let locationInLayer = myLayer.convert(locationInView, from: view.layer)

    // Wykonanie testu trafienia
    if let hitLayer = myLayer.hitTest(locationInLayer) {
        if hitLayer === myLayer {
            // Dotknięto dokładnie myLayer
            print("Dotknięto myLayer")
        } else {
            // Dotknięto podpoziom w obrębie myLayer
            print("Dotknięto podpoziom w myLayer")
            // Identyfikacja podpoziomu może wymagać dodatkowych sprawdzeń
        }
    } else {
        // Dotknięto poza myLayer i jego podpoziomami
        print("Dotknięto poza myLayer")
    }
}

Ważne punkty:

  • Koordynaty punktu dotyku (location(in:)) zawsze są powiązane z UIView. Należy je przekształcić do układu współrzędnych poziomu (convert(_, from:) lub convert(_, to:)).
  • Metoda hitTest(_:) działa na punktach w układzie współrzędnych poziomu wywołującego (myLayer.hitTest(locationInLayer)).
  • Jeśli poziom jest niewidoczny (alpha = 0 lub isHidden = true), hitTest zwróci nil. contains zwróci true, jeśli punkt znajduje się w granicach, ignorując widoczność.
  • Dla złożonych hierarchii poziomów, może być konieczne wykonanie rekurencyjnego przeszukiwania lub sprawdzenia zwróconego hitLayer.