2010-02-04 4 views
6

Estaba trabajando en una aplicación Cocoa Touch y tratando de manejar los toques al determinar qué subcapa de la capa de una vista se tocó. El código de mi controlador se veía así:¿Por qué uno tiene que usar la presentación de CALayer para las pruebas de aciertos?

CALayer *hitLayer = [self.view.layer hitTest:point]; 

Esto no estaba funcionando. Funcionaría si tocaba en la parte inferior de las subcapas, pero no en la parte superior. Después de una hora de tirones de pelo y buscando en Google, finalmente me di cuenta de que funciona si se utiliza la capa de presentación para hacer el hit-testing en lugar de la propia capa:

CALayer *hitLayer = [self.view.layer.presentationLayer hitTest:point]; 

lo tanto, he resuelto mi problema , pero mi pregunta es: ¿por qué?

He leído la guía Core Animation, y entiendo que el árbol de presentación y el árbol de representación pueden diferir del árbol del modelo de objetos. Pero no entiendo por qué el árbol de presentación (aparentemente) tendría un comportamiento de prueba de aciertos diferente. ¿El árbol de presentación y el modelo de objetos no tendrían los mismos marcos, límites, etc.?

+0

¿Cuál es la clase de self.view: UIView o CALayer? –

+0

self.view es un UIView. He corregido el código anterior para usar "self.view.layer" como debería haber sido. –

Respuesta

4

Según el CALayer documentation, parece haber una diferencia entre el modelo y el árbol de presentación con respecto a lo que se presenta al usuario (dependiendo de la animación en curso). Para la prueba de golpe, hay una referencia en el método presentationLayer:

Por ejemplo, el envío de un hitTest: mensaje a la capa de presentación se consulta los valores de presentación del árbol capa.

Así que sospecho que solo la capa de presentación tiene la información de geometría correcta para realizar la prueba de respuesta.

3

Kristopher, tuve un problema muy similar también. Sin embargo, cuando convertí el punto a la supercapa o al sistema de coordenadas de súper vistas funcionó perfectamente. No usé la capa de presentación.

//Identify the touch point in the view. Using UITapRecognizer 
CGPoint loc = [recognizer locationInView:recognizer.view]; 

//convert the point to superview co-ordinates and then identify the layer using hit test. 
CALayer *layer = [self.layer hitTest:[self convertPoint:loc toView:self.superview]]; 

Esto me devuelve la capa que se tocó, al menos por ahora. Háganos saber si cree que este es un enfoque incorrecto y, en su lugar, debería usar la capa de presentación.

Cuestiones relacionadas