1

我有一个 UIView,其中添加了 2 个 CALayers,[self.layer addSublayer:subLayerA]; //...给出了以下视图层次结构:

UIView subclass
 - backing layer (provided by UIView)
    - subLayerA
    - subLayerB

如果我在呈现 UIViewtouchesBegan视图控制器中覆盖它正确识别 CALayer 触摸:

// in view controller

#import <QuartzCore/QuartzCore.h>
//.....

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
        UITouch *touch = [touches anyObject];
        CGPoint touchPoint = [touch locationInView:self.view];
        CALayer *touchedLayer = [self.view.layer.presentationLayer hitTest:touchPoint];  // returns a copy of touchedLayer
        CALayer *actualLayer = [touchedLayer modelLayer];  // returns the actual CALayer touched
        NSLog (@"touchPoint: %@", NSStringFromCGPoint(touchPoint));
        NSLog (@"touchedLayer: %@", touchedLayer);
        NSLog (@"actualLayer: %@", actualLayer);
}

但是,如果我touchesBeganUIView中覆盖,其支持层是两个子层的父层,它将返回nullCALayer(尽管给出了正确的接触点):

// in UIView subclass

#import <QuartzCore/QuartzCore.h>
//.....

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint touchPoint = [touch locationInView:self];
    CALayer *touchedLayer = [self.layer.presentationLayer hitTest:touchPoint];  // returns a copy of touchedLayer
    CALayer *actualLayer = [touchedLayer modelLayer];  // returns the actual CALayer touched
    NSLog (@"touchPoint: %@", NSStringFromCGPoint(touchPoint));
    NSLog (@"touchedLayer: %@", touchedLayer);
    NSLog (@"actualLayer: %@", actualLayer);
}

有什么想法我哪里出错了吗?

4

2 回答 2

2

我有同样的问题..

CALayer 的 hitTest 方法需要在接收者的超层坐标中的位置。

所以添加以下行应该可以解决它: touchPoint = [self.layer convertPoint: touchPoint toLayer: self.layer.superlayer]

这可以解释为什么测试 [subLayerA hitTest:touchPoint] 有效(touchPoint 在“self”的坐标空间中,它是 subLayerA 的父级)

希望有帮助。

请参阅:https ://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CALayer_class/Introduction/Introduction.html#//apple_ref/occ/instm/CALayer/hitTest :

于 2014-05-30T15:46:33.137 回答
0

我仍然不确定为什么我在 UIView 子类中的原始代码不起作用。作为一种解决方法,我能够在每个感兴趣的层上单独测试 hitView。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint touchPoint = [touch locationInView:self];

    //check if subLayerA touched
    if ([subLayerA hitTest:touchPoint]) {
        // if not nil, then subLayerA hit
        NSLog(@"subLayerA hit");
    }
    //check if subLayerB touched
    if ([self.subLayerB hitTest:touchPoint]) {
        // if not nil, then subLayerB hit
        NSLog(@"subLayerB hit");
}

我不会将此标记为正确,因为从技术上讲,我还没有回答为什么我的原始代码不起作用 - 有人可能已经有了答案。

于 2013-05-04T13:29:56.600 回答