【问题标题】:Handling touches in CALayer在 CALayer 中处理触摸
【发布时间】:2014-03-24 05:36:10
【问题描述】:

我正在尝试在我的视图中检测触摸。

我的代码:

- (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;
}

但是我发现了问题。它只检测树中的第一层。

屏幕截图上的每个数字 - 一层。我把它从大到小画成树。

【问题讨论】:

    标签: ios iphone objective-c uiview calayer


    【解决方案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;
            }
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-09
      • 1970-01-01
      相关资源
      最近更新 更多