我正在尝试检测视图中的触摸。
我的代码:
- (CALayer *)layerForTouch:(UITouch *)touch {
UIView *view = self;
CGPoint location = [touch locationInView:view];
location = [view convertPoint:location toView:nil];
CALayer *hitPresentationLayer = [view.layer.presentationLayer hitTest:location];
if (hitPresentationLayer) {
return hitPresentationLayer.modelLayer;
}
return nil;
}
但我发现了问题。它只检测树中的第一层。
屏幕截图上的每个数字 - 一层。我正在把它从最大到最小的树上画出来。
答案 0 :(得分:1)
如果您的最顶层覆盖整个屏幕(或其他下层),那么您将在hitTest检查期间获得最顶层。如果要在下面进一步检查,可以对所有图层执行containsPoint检查。请在下面找到一些示例代码
@interface ViewController ()
@property (nonatomic, strong) CALayer *layer1;
@property (nonatomic, strong) CALayer *layer2;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
CALayer *layer = [[CALayer alloc] init];
layer.frame = (CGRect) { 10, 10, 100, 100 };
[self.view.layer addSublayer:layer];
layer.backgroundColor = [UIColor redColor].CGColor;
self.layer1 = layer;
layer = [[CALayer alloc] init];
layer.frame = (CGRect) { 60, 60, 100, 100 };
[self.view.layer addSublayer:layer];
layer.backgroundColor = [UIColor blueColor].CGColor;
self.layer2 = layer;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint touchPoint = [(UITouch*)[touches anyObject] locationInView:self.view];
CALayer *touchedLayer = [self.view.layer.presentationLayer hitTest:touchPoint];
CALayer *originalLayer = [touchedLayer modelLayer];
if (originalLayer == self.layer1) { NSLog(@"layer 1 touched"); }
if (originalLayer == self.layer2) { NSLog(@"layer 2 touched"); }
for ( CALayer *layer in @[self.layer1, self.layer2])
{
CGPoint point = [layer convertPoint:touchPoint fromLayer:self.view.layer];
NSLog(@"layer %@ containsPoint ? %@",layer, [layer containsPoint:point]? @"YES":@"NO");
NSLog(@"original point : %@ | converted point : %@",NSStringFromCGPoint(touchPoint),NSStringFromCGPoint(point));
}
}
@end
或者您可以尝试使用CAShapeLayers&与ShapeLayer的CGPath匹配,看看它是否像下面的例子一样触及..
@interface ViewController ()
@property (nonatomic, strong) CALayer *layer1;
@property (nonatomic, strong) CALayer *layer2;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init];
shapeLayer.path = [UIBezierPath bezierPathWithRect:(CGRect){ 0,0,100,10 }].CGPath;
shapeLayer.backgroundColor = [UIColor redColor].CGColor;
shapeLayer.frame = (CGRect){20, 20, 100, 100};
[self.view.layer addSublayer:shapeLayer];
self.layer1 = shapeLayer;
shapeLayer = [[CAShapeLayer alloc] init];
shapeLayer.path = [UIBezierPath bezierPathWithRect:(CGRect){ 0,0,10,100 }].CGPath;
shapeLayer.backgroundColor = [[UIColor blueColor] colorWithAlphaComponent:0.6].CGColor;
shapeLayer.frame = (CGRect){60, 60, 100, 100};
[self.view.layer addSublayer:shapeLayer];
self.layer2 = shapeLayer;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint touchPoint = [(UITouch*)[touches anyObject] locationInView:self.view];
CALayer *touchedLayer = [self.view.layer.presentationLayer hitTest:touchPoint];
CALayer *originalLayer = [touchedLayer modelLayer];
for ( CAShapeLayer *layer in @[self.layer1, self.layer2])
{
if (![layer isKindOfClass:[CAShapeLayer class]]) { continue; }
CGPoint point = [layer convertPoint:touchPoint fromLayer:self.view.layer];
if (CGPathContainsPoint(layer.path, 0, point, 0))
{
NSLog(@"match found");
if (originalLayer == self.layer1) { NSLog(@"layer 1 touched"); }
if (originalLayer == self.layer2) { NSLog(@"layer 2 touched"); }
return;
}
}
}