如何在CALayer上获取触摸事件?

24

我是iPhone SDK的新手。目前我正在使用CALayer进行编程,我非常喜欢它 - 它不像UIView那样昂贵,并且比OpenGL ES精灵少写很多代码。

我有一个问题:是否可能在CALayer上获取触摸事件? 我知道如何在UIView上获取触摸事件。

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 

但是我找不到任何关于如何在CALayer对象上获取触摸事件的资料,例如在3D空间中浮动的橙色正方形。我拒绝相信我是唯一一个对此感到好奇的人。

非常感谢帮助!

4个回答

30

好的 - 我回答了自己的问题!假设您在视图控制器的主层中有一堆CALayer,并且希望在触摸它们时将它们的不透明度设置为0.5。请在您的视图控制器类的.m文件中实现以下代码:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if ([touches count] == 1) {
        for (UITouch *touch in touches) {
            CGPoint point = [touch locationInView:[touch view]];
            point = [[touch view] convertPoint:point toView:nil];

            CALayer *layer = [(CALayer *)self.view.layer.presentationLayer hitTest:point];

            layer = layer.modelLayer;
            layer.opacity = 0.5;
        }
    }
}

1
为了更清晰明了,以下是翻译的注意事项:
  1. for循环有些笨拙,因为你已经验证只有一个触摸。通常的做法是使用[touches anyObject]或[touches objectAtIndex:0]创建一个指向触摸的指针。
  2. 不要使用convertPoint:,直接在locationInView:中传递“nil”。这将给出窗口坐标系中的触摸位置,因此下一行是多余的。
- Rab
1
我知道这是一个相当老的问题。但是只是为了那些好奇的人。@Rab大多数是正确的,除了[touches objectAtIndex:0] NSset,它代表一组触摸,并没有objectAtIndex选择器。 - Eugene P
+1 @EugeneProkoshev,好观点。有可能有人会将触摸事件放入NSArray中,但在这种情况下,我们只有不带索引的NSSet。感谢澄清。 :) - Rab

8
与第一个答案类似。
- (CALayer *)layerForTouch:(UITouch *)touch {
    UIView *view = self.view;

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

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CALayer *hitLayer = [self layerForTouch:touch];

    // do layer processing...
}


1

我发现我得到了错误的坐标

point = [[touch view] convertPoint:point toView:nil];

我不得不将它更改为

point = [[touch view] convertPoint:point toView:self.view];

获取正确的层级


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接