I was working on a Cocoa Touch application, and trying to handle touches by determining which sublayer of a view's layer was touched. My controller's code looked like this:
CALayer *hitLayer = [self.view.layer hitTest:point];
This wasn't working. It would work if I tapped at the bottoms of sublayers, but not at the tops. After an hour of hair-pulling and Googling, I finally figured out that it works if one uses the presentation layer to do the hit-testing instead of the layer itself:
CALayer *hitLayer = [self.view.layer.presentationLayer hitTest:point];
So, I've solved my problem, but my question is: Why?
I've read through the Core Animation guide, and I understand that the presentation tree and rendering tree can differ from the object-model tree. But I don't understand why the presentation tree would (apparently) have different hit-testing behavior. Wouldn't the presentation tree and object-model have the same frames, bounds, etc.?
According to the CALayer documentation, there seems to be a difference between the model and the presentation tree regarding what is presented to the user (depending on the ongoing animation). For hit testing, there is a reference in the presentationLayer
method:
For example, sending a hitTest: message to the presentationLayer will query the presentation values of the layer tree.
So I suspect that only presentation layer has the right geometry information to perform the hit test.
Kristopher, I had a very similar issue too. However, when I converted the point to the super layer or super views coordinate system it worked perfectly. I did not use the presentation layer.
//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]];
This returns me the layer that was touched, at least for now. Let us know if you think this is a wrong approach and I should be using presentation-layer instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With