Trigger an action when a CALayer is touched?

2019-02-05 13:52发布

So I have been looking all over and I haven't quite found what I am looking for.

I have a view and then a subview of that view. On that second view I create CALayers depending on what coordinates I give it. I want to be able to touch any of those CALayers and trigger something.

I have found different pieces of code that look like they can help, but I haven't been able to implement them.

For example:

-(void)touchesEnded:(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;

} } } 

and also this....

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch *touch = [touches anyObject];

    // If the touch was in the placardView, bounce it back to the center
    if ([touch view] == placardView) {
        // Disable user interaction so subsequent touches don't interfere with animation
        self.userInteractionEnabled = NO;
        [self animatePlacardViewToCenter];
        return;
    }       
}

I am still pretty much a beginner to this stuff. I was wondering if anyone can tell me how to do this. Thanks for any help.

1条回答
We Are One
2楼-- · 2019-02-05 14:19

CALayer cannot react on touch events directly, but lots of other objects in your program can - for example the UIView which is hosting the layers.

Events, such as an event that is generated by system when screen is touched, are being sent over so called "responder chain". So when the screen is touched, a message is sent (in other words - method is called) to the UIView which lies at the location of touch. For touches there are three possible messages: touchesBegan:withEvent:, touchesMoved:withEvent: and touchesEnded:withEvent:.

If that view does not implement the method, the system will try to send it to the parent view (superview in iOS language). It's trying to send it until it reaches the top view. If none of the views implement the method, it tries to be delivered to current view-controller, then it's parent controller, then to the application object.

That means you can react on touch events by implementing mentioned methods in any of these objects. Usually the hosting view or the current view-controller are the best candidates.

Let's say you implement it in the view. Next task is to figure out which of your layers have been touched, for this you can use convenient method convertPoint:toLayer:.

For example here's it might look like in a view controller:

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
    CGPoint p = [(UITouch*)[touches anyObject] locationInView:self.worldView];
    for (CALayer *layer in self.worldView.layer.sublayers) {
        if ([layer containsPoint:[self.worldView.layer convertPoint:p toLayer:layer]]) {
            // do something
        }
    }
}
查看更多
登录 后发表回答