Ответ 1
Что-то, на что я наткнулся, почесывая голову над подобной проблемой, заключается в том, что CALayer использует containsPoint:
, когда вы отправляете его hitTest:
Его поведение по умолчанию - это тест против границ, но мы можем переопределить его и проверить его на альфа-канал, а просто использовать CALayer, встроенный в тестирование hit, чтобы справиться с остальными:
- (BOOL) containsPoint:(CGPoint)p
{
return CGRectContainsPoint(self.bounds, p) && !ImagePointIsTransparent(self.contents, p)) return YES;
}
Здесь обсуждается тестирование одного пикселя alpha на Извлечение значения альфа-пикселя для UIImage
Это сработало для моих целей:
static BOOL ImagePointIsTransparent(CGImageRef image, CGPoint p)
{
uint8_t alpha;
CGContextRef context = CGBitmapContextCreate(&alpha, 1, 1, 8, 1, NULL, kCGImageAlphaOnly);
CGContextDrawImage(context, CGRectMake(-p.x, -p.y, CGImageGetWidth(image), CGImageGetHeight(image)), image);
CGContextRelease(context);
return alpha == 0;
}
(Если вы используете renderInContext:
для рисования на CALayer, а не для установки его содержимого, то это будет сложнее. Это может быть полезно в этом случае: http://www.cimgf.com/2009/02/03/record-your-core-animation-animation/)