Question

I have a CALayer with hitTesting that works fine. The code is something like this:

- (void)setup
{
    _maskLayer = [CAShapeLayer layer];
    _maskLayer.fillColor = [UIColor whiteColor].CGColor;
    _maskLayer.path = somePath;

    _theLayer.frame = CGRectMake(0, 0, size.width, size.height);
    // Taps work fine if we do not apply the mask
    // _theLayer.mask = _maskLayer;
}

- (IBAction)tapOnView:(UITapGestureRecognizer *)sender
{
    CGPoint point = [sender locationInView:theView];
    CALayer *subLayer = [_theLayer.presentationLayer hitTest:point].modelLayer;

    if (subLayer != _theLayer && subLayer != nil) {
        // Do something with the sublayer which the user touched
    }
}

The problem is that if I uncomment the line with the mask, my hit testing always returns nil. Why does the mask kill hit testing? It appears correct visually.

Was it helpful?

Solution

It turns out that hit testing requires the point to be inside the bounds of the CALayer, but what is not documented is that it also has to be inside the bounds of the mask. So I changed my code like this and it worked:

    _theLayer.frame = CGRectMake(0, 0, size.width, size.height);

    // Apply a mask
    _maskLayer.frame = _theLayer.frame;
    _theLayer.mask = _maskLayer;

It took me a few hours to figure this out, so I wanted to share.

OTHER TIPS

I used the accepted answer but still had some issue because you should use bounds just to prevent your mask not showing if your layer is other than 0,0 Also, this is the swift solution:

theLayer.frame = CGRecti(x: 0, y, 0: width: size.width, height:size.height) 

maskLayer.frame = theLayer.bounds
theLayer.mask = maskLayer
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top