Alors que la plupart des documents Apple sont très bien écrits, je pense que le « Guide de gestion des événements pour iOS » est une exception. J'ai du mal à comprendre clairement ce qui y est décrit.
Le document dit,
Dans le test de positionnement, une fenêtre appelle
hitTest:withEvent:
la vue la plus haute de la hiérarchie de vues; cette méthode procède en appelant de manière récursivepointInside:withEvent:
sur chaque vue de la hiérarchie de vues qui renvoie OUI, en descendant la hiérarchie jusqu'à ce qu'elle trouve la sous-vue dans les limites de laquelle le contact a eu lieu. Cette vue devient la vue de test de succès.
Est-ce que c'est comme si seule hitTest:withEvent:
la vue la plus haute est appelée par le système, qui appelle pointInside:withEvent:
toutes les sous-vues, et si le retour d'une sous-vue spécifique est OUI, alors les appels pointInside:withEvent:
des sous-classes de cette sous-vue?
Réponses:
Cela semble une question assez fondamentale. Mais je suis d'accord avec vous, le document n'est pas aussi clair que d'autres documents, voici donc ma réponse.
La mise
hitTest:withEvent:
en œuvre de dans UIResponder effectue les opérations suivantes:pointInside:withEvent:
deself
hitTest:withEvent:
retournenil
. la fin de l'histoire.hitTest:withEvent:
messages à ses sous-vues. il commence à partir de la sous-vue de niveau supérieur et continue vers d'autres vues jusqu'à ce qu'une sous-vue renvoie un non-nil
objet ou que toutes les sous-vues reçoivent le message.nil
objet pour la première fois, la premièrehitTest:withEvent:
renvoie cet objet. la fin de l'histoire.nil
objet, la premièrehitTest:withEvent:
renvoieself
Ce processus se répète de manière récursive, de sorte que la vue feuille de la hiérarchie de vues est normalement renvoyée.
Cependant, vous pouvez passer outre
hitTest:withEvent
pour faire quelque chose différemment. Dans de nombreux cas, le remplacementpointInside:withEvent:
est plus simple et fournit toujours suffisamment d'options pour modifier la gestion des événements dans votre application.la source
hitTest:withEvent:
toutes les sous-vues sont finalement exécutées?hitTest:withEvent:
vos vues (etpointInside
si vous le souhaitez), imprimez un journal et appelez[super hitTest...
pour savoir quihitTest:withEvent:
est appelé dans quel ordre.Je pense que vous confondez les sous-classes avec la hiérarchie des vues. Ce que dit le doc est le suivant. Supposons que vous ayez cette hiérarchie de vues. Par hiérarchie, je ne parle pas de hiérarchie de classes, mais de vues dans la hiérarchie de vues, comme suit:
Dites que vous mettez votre doigt à l'intérieur
D
. Voici ce qui va se passer:hitTest:withEvent:
est appeléeA
, la vue la plus haute de la hiérarchie des vues.pointInside:withEvent:
est appelé récursivement sur chaque vue.pointInside:withEvent:
est appeléA
, et retourneYES
pointInside:withEvent:
est appeléB
, et retourneNO
pointInside:withEvent:
est appeléC
, et retourneYES
pointInside:withEvent:
est appeléD
, et retourneYES
YES
, il regardera la hiérarchie pour voir la sous-vue où le contact a eu lieu. Dans ce cas, à partirA
,C
etD
, il seraD
.D
sera la vue hit-testla source
hitTest:withEvent:
B, C et D sont également invoqués. Que se passe-t-il si D est une sous-vue de C et non de A? Je pense que je suis confus ...A
reviendrait -il pasYES
aussi bien, tout commeC
etD
fait?Je trouve ce Hit-Testing dans iOS très utile
Modifier Swift 4:
la source
Merci pour les réponses, ils m'ont aidé à résoudre la situation avec des vues "superposées".
Supposons
X
- le toucher de l'utilisateur.pointInside:withEvent:
sur lesB
retoursNO
, donc leshitTest:withEvent:
retoursA
. J'ai écrit la catégorieUIView
pour gérer le problème lorsque vous avez besoin de recevoir le toucher sur la vue la plus visible .userInteractionEnabled
une valeurNO
;self
,self
sera considéré comme un résultat potentiel.Remarque,
[self.subviewsreverseObjectEnumerator]
nécessaire pour suivre la hiérarchie des vues de haut en bas. Et vérifiez pourclipsToBounds
vous assurer de ne pas tester les sous-vues masquées.Usage:
hitTest:withEvent:
par ceciLe guide officiel d'Apple fournit également de bonnes illustrations.
J'espère que cela aide quelqu'un.
la source
Cela montre comme cet extrait!
la source
L'extrait de @lion fonctionne comme un charme. Je l'ai porté sur swift 2.1 et je l'ai utilisé comme extension d'UIView. Je le poste ici au cas où quelqu'un en aurait besoin.
Pour l'utiliser, remplacez simplement hitTest: point: withEvent dans votre uiview comme suit:
la source
Diagramme de classe
Test de succès
Trouver un
First Responder
First Responder
dans ce cas est laUIView
point()
méthode la plus profonde qui a renvoyé truehitTest()
Ressemble en interneEnvoyer l'événement tactile au
First Responder
Jetons un coup d'œil à l'exemple
Chaîne de répondeurs
Jetez un œil à l'exemple
[Android onTouch]
la source