Sobes.tech
Middle

Hoe bepaal je of de gebruiker op een laag (layer) in de app heeft geklikt?

sobes.tech AI

Antwoord van AI

Om aanrakingen op CALayer te detecteren, kunnen verschillende benaderingen worden gebruikt:

  1. Gebruik hitTest(_:event:) in de view:

    • UIView heeft de methode hitTest(_:with:), die recursief door de hiërarchie van subviews gaat en de meest diepe view retourneert die het gegeven punt bevat.
    • Deze methode houdt standaard rekening met de lagen die aan views gekoppeld zijn.
    • Je kunt hitTest(_:with:) overschrijven in een aangepaste view voor meer controle of om aanrakingen direct op sublagen te behandelen die niet gekoppeld zijn aan views.
  2. Transformeer coördinaten met convert:

    • Bij het ontvangen van een aanrakingsevent (bijvoorbeeld in UIView-methoden), heb je de coördinaten van de aanraking ten opzichte van het venster (UIWindow) of de view.
    • Om te bepalen of de aanraking op een specifieke laag is gevallen, moet je deze coördinaten omzetten naar het coördinatensysteem van die laag.
    • Hiervoor gebruik je de methoden convert(_:from:) of convert(_:to:) van CALayer.
    • Na de conversie kun je controleren of het punt binnen de grenzen van de laag ligt (bounds) of meer specifieke controles uitvoeren zoals contains(_:).
  3. Voeg UITapGestureRecognizer toe aan de view:

    • Je kunt een UITapGestureRecognizer toevoegen aan de UIView die met de laag is verbonden.
    • In de gesture-handler krijg je de locatie van de aanraking ten opzichte van de view.
    • Vervolgens gebruik je de coördinatentransformatie (punt 2) om te controleren of het punt binnen de laag of zijn sublagen ligt.
  4. Maak voor elke interactieve laag een UIView:

    • Als je lagen hebt die interactief moeten zijn, is de eenvoudigste manier om voor elke laag een UIView te maken.
    • Plaats en pas de grootte van de UIView aan zodat deze overeenkomt met de laag.
    • Voeg gesture-handlers (UITapGestureRecognizer) toe of overschrijf de methoden voor het afhandelen van aanrakingen (touchesBegan, touchesEnded, etc.) in deze view.
    • Dit is de meest idiomatische manier om gebruikersinvoer te verwerken in UIKit, omdat UIView hiervoor speciaal is ontworpen.

Voorbeeld van gebruik van hitTest in UIView:

// In een aangepaste `UIView`
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    // Converteer het aanrakingpunt naar de coördinaten van de sublaag
    let pointInLayer = mySublayer.convert(point, from: layer!)
    
    // Controleer of het punt binnen de grenzen van de sublaag ligt
    if mySublayer.contains(pointInLayer) {
        // Als het punt binnen de sublaag ligt, kun je deze view of een andere teruggeven
        // of de benodigde acties uitvoeren.
        // In dit geval bepalen we dat de aanraking "op" de sublaag was.
        print("Aanraking op mySublayer")
        // Je kunt nil teruggeven als je niet wilt dat deze view verder behandelt, of super.hitTest
    }
    
    // Sta standaard hitTest toe om andere gevallen te behandelen
    return super.hitTest(point, with: event)
}

Voorbeeld van het gebruik van coördinatentransformatie in een gesture-handler:

// In een aangepaste `UIView` met een gekoppelde `UITapGestureRecognizer`
@objc func handleTap(_ sender: UITapGestureRecognizer) {
    let tapLocationInView = sender.location(in: self)
    
    // Converteer de aanrakinglocatie naar de coördinaten van de sublaag
    let tapLocationInSublayer = mySublayer.convert(tapLocationInView, from: layer!)
    
    // Controleer of het punt binnen de grenzen van de sublaag ligt
    if mySublayer.contains(tapLocationInSublayer) {
        print("Aanraking op mySublayer")
        // Voer acties uit die verband houden met de aanraking op de sublaag
    }
}