Sobes.tech
Middle

Πώς μπορούμε να προσδιορίσουμε αν ένας χρήστης έκανε κλικ σε ένα στρώμα (layer);

sobes.tech AI

Απάντηση από AI

Μπορείτε να χρησιμοποιήσετε το testing hit: να προσδιορίσετε σε ποιο επίπεδο έγινε ακριβώς η αφή. Το Core Animation παρέχει δύο μεθόδους για αυτό:

  1. hitTest(_:):

    • Ελέγχει αν το σημείο βρίσκεται εντός των ορίων του επιπέδου ή οποιουδήποτε από τα υπο-επίπεδά του.
    • Επιστρέφει το πιο βαθύ υπο-επίπεδο (ή το ίδιο το επίπεδο) που περιέχει το σημείο.
    • Λαμβάνει υπόψη το isHidden = true.
  2. contains(_:):

    • Ελέγχει μόνο αν το σημείο βρίσκεται εντός των ορίων του ίδιου του επιπέδου.
    • Δεν λαμβάνει υπόψη την ιεραρχία των υπο-επιπέδων.
    • Δεν λαμβάνει υπόψη το isHidden.

Συνήθως, χρησιμοποιείται το hitTest, καθώς είναι πιο ακριβές για τον προσδιορισμό της διαδραστικότητας.

Παράδειγμα χρήσης του hitTest σε χειριστή αφής:

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

    let locationInView = touch.location(in: view)

    // Μετατρέπουμε το σημείο από τις συντεταγμένες της προβολής στις συντεταγμένες του επιπέδου
    let locationInLayer = myLayer.convert(locationInView, from: view.layer)

    // Εκτελούμε το hit test
    if let hitLayer = myLayer.hitTest(locationInLayer) {
        if hitLayer === myLayer {
            // Ακριβώς στο myLayer
            print("Το myLayer αγγίχτηκε")
        } else {
            // Σε υπο-επίπεδο μέσα στο myLayer
            print("Σε υπο-επίπεδο μέσα στο myLayer")
            // Η ταυτοποίηση του υπο-επιπέδου μπορεί να απαιτεί πρόσθετους ελέγχους
        }
    } else {
        // Εκτός του myLayer και των υπο-επιπέδων του
        print("Εκτός του myLayer")
    }
}

Σημαντικά σημεία:

  • Οι συντεταγμένες του σημείου αφής (location(in:)) είναι πάντα συνδεδεμένες με το UIView. Πρέπει να μετατραπούν στο σύστημα συντεταγμένων του επιπέδου (convert(_, from:) ή convert(_, to:)).
  • Η μέθοδος hitTest(_:) λειτουργεί με σημεία στο σύστημα συντεταγμένων του καλούντος επιπέδου (myLayer.hitTest(locationInLayer)).
  • Αν το επίπεδο είναι αόρατο (alpha = 0 ή isHidden = true), το hitTest θα επιστρέψει nil. Το contains θα επιστρέψει true αν το σημείο βρίσκεται εντός των ορίων, αγνοώντας την ορατότητα.
  • Για πολύπλοκες ιεραρχίες επιπέδων, μπορεί να χρειαστεί αναδρομική αναζήτηση ή έλεγχος του επιστρεφόμενου hitLayer.