Sobes.tech
Middle

Jak určit, že uživatel klikl na vrstvu (layer) v aplikaci?

sobes.tech AI

Odpověď od AI

Pro určení stisku na CALayer lze použít několik přístupů:

  1. Použití hitTest(_:event:) v pohledu (View):

    • UIView má metodu hitTest(_:with:), která rekurzivně prochází hierarchii podpohledů a vrací nejhlubší podpohled obsahující daný bod.
    • Tato metoda implicitně zohledňuje vrstvy spojené s pohledy.
    • Můžete přepsat hitTest(_:with:) ve vlastním pohledu pro detailnější kontrolu nebo pro zpracování stisků přímo na podvrstvách.
  2. Transformace souřadnic pomocí convert:

    • Při zachycení události dotyku (například v metodách UIView) máte souřadnice dotyku vzhledem k oknu (UIWindow) nebo pohledu.
    • Aby bylo možné určit, zda dotek zasáhl určitý vrstvu, je třeba tyto souřadnice převést do souřadnicového systému této vrstvy.
    • K tomu slouží metody convert(_:from:) nebo convert(_:to:) CALayer.
    • Po převodu lze zkontrolovat, zda bod leží uvnitř hranic vrstvy (bounds) nebo použít specifičtější kontroly, například contains(_:).
  3. Připojení UITapGestureRecognizer k pohledu:

    • Můžete připojit gesto UITapGestureRecognizer k UIView, který je spojen s vrstvou.
    • V obslužné metodě gest, získáte polohu dotyku vzhledem k pohledu.
    • Poté použijete přístup s převodem souřadnic (bod 2) k ověření, zda je bod dotyku uvnitř požadované vrstvy nebo jejích podvrstev.
  4. Vytvoření UIView pro každou interaktivní vrstvu:

    • Pokud máte vrstvy, které mají být interaktivní, nejjednodušší způsob je vytvořit pro každou takovou vrstvu odpovídající UIView.
    • Umístěte a nastavte velikost UIView podle vrstvy.
    • Připojte obslužné rutiny gest (UITapGestureRecognizer) nebo přepište metody zpracování událostí dotyku (touchesBegan, touchesEnded atd.) v tomto pohledu.
    • To je nejidiomatickější způsob zpracování uživatelského vstupu v UIKit, protože UIView je k tomu speciálně určen.

Příklad použití hitTest v UIView:

// V uživatelském `UIView`
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    // Převod bodu dotyku na souřadnice podvrstvy
    let pointInLayer = mySublayer.convert(point, from: layer!)
    
    // Kontrola, zda je bod uvnitř hranic podvrstvy
    if mySublayer.contains(pointInLayer) {
        // Pokud je bod uvnitř podvrstvy, můžeme vrátit sebe nebo jiný pohled,
        // nebo provést potřebné akce.
        print("Stisk na mySublayer")
        // Můžeme vrátit nil, pokud nechceme, aby tento pohled dále zpracovával,
        // nebo volat super.hitTest(point, with: event) pro zachování standardního chování.
    }
    
    // Povolíme standardní `hitTest` pro ostatní případy
    return super.hitTest(point, with: event)
}

Příklad použití převodu souřadnic v handleru gest:

// V uživatelském `UIView` s připojeným `UITapGestureRecognizer`
@objc func handleTap(_ sender: UITapGestureRecognizer) {
    let tapLocationInView = sender.location(in: self)
    
    // Převod bodu dotyku z souřadnic pohledu do souřadnic podvrstvy
    let tapLocationInSublayer = mySublayer.convert(tapLocationInView, from: layer!)
    
    // Kontrola, zda je bod uvnitř hranic podvrstvy
    if mySublayer.contains(tapLocationInSublayer) {
        print("Stisk na mySublayer")
        // Vykonat akce spojené se stiskem na podvrstvě
    }
}