1

[self.layer addSublayer:subLayerA]; //...次のビュー階層を与える2 つの CALayers が追加された UIView があります。

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

UIView を表示するビュー コントローラーでオーバーライドtouchesBeganすると、触れた 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);
}

ただし、バッキング レイヤーが 2 つのサブレイヤーの親であるUIViewでオーバーライドtouchesBeganすると、CALayer が返されます (ただし、正しい touchPoint が得られます)。null

// 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 は、subLayerA の親である「self」の座標空間にあります)。

それが役立つことを願っています。

参照: 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 に答える