Si bien la mayoría de los documentos de Apple están muy bien escritos, creo que la ' Guía de manejo de eventos para iOS ' es una excepción. Es difícil para mí entender claramente lo que se ha descrito allí.
El documento dice:
En las pruebas de impacto, una ventana llama
hitTest:withEvent:a la vista superior de la jerarquía de vistas; Este método se realiza recurriendo recursivamentepointInside:withEvent:a cada vista en la jerarquía de vistas que devuelve SÍ, avanzando hacia abajo hasta encontrar la subvista dentro de cuyos límites se produjo el toque. Esa vista se convierte en la vista de prueba de impacto.
Entonces, ¿es así que solo hitTest:withEvent:el sistema llama a la vista superior, que llama pointInside:withEvent:a todas las subvistas, y si el retorno de una subvista específica es SÍ, entonces llama a pointInside:withEvent:las subclases de esa subvista?

Respuestas:
Parece una pregunta bastante básica. Pero estoy de acuerdo con usted, el documento no es tan claro como otros documentos, así que aquí está mi respuesta.
La implementación de
hitTest:withEvent:en UIResponder hace lo siguiente:pointInside:withEvent:deselfhitTest:withEvent:regresanil. El fin de la historia.hitTest:withEvent:respuesta es SÍ, envía mensajes a sus subvistas. comienza desde la subvista de nivel superior y continúa a otras vistas hasta que una subvista devuelve un nonilobjeto, o todas las subvistas reciben el mensaje.nilobjeto la primera vez, la primerahitTest:withEvent:devuelve ese objeto. El fin de la historia.nilobjeto, la primerahitTest:withEvent:devuelveselfEste proceso se repite de forma recursiva, por lo que normalmente se devuelve la vista de hoja de la jerarquía de vistas.
Sin embargo, puede anular
hitTest:withEventhacer algo diferente. En muchos casos, la anulaciónpointInside:withEvent:es más simple y aún ofrece suficientes opciones para modificar el manejo de eventos en su aplicación.fuente
hitTest:withEvent:todas las subvistas se ejecutan eventualmente?hitTest:withEvent:sus vistas (ypointInsidesi lo desea), imprima un registro y llame[super hitTest...para averiguar quiénhitTest:withEvent:se llama en qué orden.Creo que estás confundiendo las subclases con la jerarquía de vistas. Lo que dice el documento es lo siguiente. Digamos que tiene esta jerarquía de vistas. Por jerarquía no estoy hablando de jerarquía de clases, sino de vistas dentro de la jerarquía de vistas, de la siguiente manera:
Digamos que pones tu dedo adentro
D. Esto es lo que sucederá:hitTest:withEvent:se llamaA, la vista superior de la jerarquía de vistas.pointInside:withEvent:se llama recursivamente en cada vista.pointInside:withEvent:se llamaAy devuelveYESpointInside:withEvent:se llamaBy devuelveNOpointInside:withEvent:se llamaCy devuelveYESpointInside:withEvent:se llamaDy devuelveYESYES, mirará hacia abajo en la jerarquía para ver la subvista donde tuvo lugar el contacto. En este caso, desdeA,CyD, seráD.Dserá la vista de prueba de éxitofuente
hitTest:withEvent:B, C y D también se invocan. ¿Qué sucede si D es una subvista de C, no A? Creo que se confundió ...AvolverYES, así, del mismo modoC, yDlo hace?Encuentro que este Hit-Testing en iOS es muy útil
Editar Swift 4:
fuente
Gracias por las respuestas, me ayudaron a resolver situaciones con vistas de "superposición".
Asumir
X: toque del usuario.pointInside:withEvent:enBdevolucionesNO, por lo quehitTest:withEvent:vuelveA. Escribí la categoríaUIViewpara manejar el problema cuando necesita recibir un toque en la vista superior más visible .userInteractionEnabledset toNO;self,selfse considerará como resultado potencial.Tenga en cuenta que era
[self.subviewsreverseObjectEnumerator]necesario seguir la jerarquía de vistas de arriba hacia abajo. Y compruebe paraclipsToBoundsasegurarse de no probar subvistas enmascaradas.Uso:
hitTest:withEvent:con estoLa Guía oficial de Apple también ofrece algunas buenas ilustraciones.
Espero que esto ayude a alguien.
fuente
¡Se muestra como este fragmento!
fuente
El fragmento de @lion funciona a las mil maravillas. Lo porté a Swift 2.1 y lo usé como una extensión de UIView. Lo estoy publicando aquí en caso de que alguien lo necesite.
Para usarlo, simplemente anule hitTest: point: withEvent en su uiview de la siguiente manera:
fuente
Diagrama de clase
Prueba de golpe
Encontrar un
First ResponderFirst Responderen este caso es elUIViewpoint()método más profundo de los cuales devuelve verdaderoInternamente se
hitTest()ve comoEnviar evento táctil al
First ResponderVeamos un ejemplo.
Cadena de respuesta
Mira el ejemplo
[Android onTouch]
fuente