Как получить сенсорное событие на CALayer? - PullRequest
21 голосов
/ 21 февраля 2009

Я новичок в iPhone SDK. Прямо сейчас я программирую на CALayers, которые мне очень нравятся - не так дорого, как UIViews, и гораздо меньше кода, чем спрайты OpenGL ES.

У меня есть вопрос: возможно ли получить сенсорное событие на CALayer? Я понимаю, как получить сенсорное событие на UIView с

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

но я нигде не могу найти, как получить событие касания для объекта CALayer, например, оранжевого квадрата, плавающего в трехмерном пространстве. Я отказываюсь верить, что я единственный, кому это интересно.

Я ценю любую помощь!

Ответы [ 4 ]

29 голосов
/ 21 февраля 2009

ОК - ответил на мой вопрос! Допустим, у вас есть группа CALayers в основном слое контроллера представления, и вы хотите, чтобы они при касании их достигли непрозрачности 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;
        }
    }
}
8 голосов
/ 21 августа 2012

Аналогично первому ответу.

- (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 голос
/ 18 июня 2012

Я обнаружил, что получаю неправильные координаты с

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

Я должен был изменить его на

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

Чтобы получить правильный слой

0 голосов
/ 04 сентября 2018

Егор Т ответ обновлено для Swift 4:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
{
    super.touchesBegan(touches, with: event)

    if let touch = touches.first, let touchedLayer = self.layerFor(touch)
    {
        //Here you will have the layer as "touchedLayer"
    }
}

private func layerFor(_ touch: UITouch) -> CALayer?
{
    let view = self.view
    let touchLocation = touch.location(in: view)
    let locationInView = view.convert(touchLocation, to: nil)

    let hitPresentationLayer = view.layer.presentation()?.hitTest(locationInView)
    return hitPresentationLayer?.model()
}
...