Sobes.tech
Middle

Jak lze určit, zda uživatel klikl na vrstvu (layer)?

sobes.tech AI

Odpověď od AI

Lze použít hit testing: určit, na které vrstvě došlo přesně k dotyku. Core Animation poskytuje pro tento účel dvě metody:

  1. hitTest(_:):

    • Kontroluje, zda se bod nachází uvnitř hranic vrstvy nebo kteréhokoliv jejího podvrstvy.
    • Vrací nejhlubší podvrstvu (nebo samotnou vrstvu), která bod obsahuje.
    • Zohledňuje isHidden = true.
  2. contains(_:):

    • Kontroluje pouze, zda se bod nachází uvnitř hranic samotné vrstvy.
    • Nezohledňuje hierarchii podvrstev.
    • Nezohledňuje isHidden.

Obvykle se používá hitTest, protože je přesnější pro určení interaktivity.

Příklad použití hitTest v obsluze dotyku:

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

    let locationInView = touch.location(in: view)

    // Převod bodu z souřadnic view do souřadnic vrstvy
    let locationInLayer = myLayer.convert(locationInView, from: view.layer)

    // Provedení hit testu
    if let hitLayer = myLayer.hitTest(locationInLayer) {
        if hitLayer === myLayer {
            // Přesně na myLayer
            print("Dotek na myLayer")
        } else {
            // Na podvrstvu uvnitř myLayer
            print("Dotek na podvrstvu uvnitř myLayer")
            // Identifikace podvrstvy může vyžadovat další kontroly
        }
    } else {
        // Dotek mimo myLayer a jeho podvrstvy
        print("Dotek mimo myLayer")
    }
}

Důležité body:

  • Souřadnice bodu doteku (location(in:)) jsou vždy spojeny s UIView. Je nutné je převést do souřadnicového systému vrstvy (convert(_, from:) nebo convert(_, to:)).
  • Metoda hitTest(_:) pracuje s body v souřadnicovém systému volající vrstvy (myLayer.hitTest(locationInLayer)).
  • Pokud je vrstva neviditelná (alpha = 0 nebo isHidden = true), hitTest vrátí nil. contains vrátí true, pokud je bod uvnitř hranic, ignorujíc viditelnost.
  • U složitých hierarchií vrstev může být nutné provést rekurzivní hledání nebo zkontrolovat vrácenou hitLayer.