Jacob KB
Jacob KB

Reputation: 31

Events in CALayer

I am using CALayers animation in my code. Below is my code

CALayer *backingLayer = [CALayer layer];
        backingLayer.contentsGravity = kCAGravityResizeAspect;
        // set opaque to improve rendering speed
        backingLayer.opaque = YES;


        backingLayer.backgroundColor = [UIColor whiteColor].CGColor;

        backingLayer.frame = CGRectMake(0, 0, templateWidth, templateHeight);

        [backingLayer addSublayer:view.layer];
        CGFloat scale = [[UIScreen mainScreen] scale];
        CGSize size = CGSizeMake(backingLayer.frame.size.width*scale, backingLayer.frame.size.height*scale);
        UIGraphicsBeginImageContextWithOptions(size, NO, scale);
        CGContextRef context = UIGraphicsGetCurrentContext();
        [backingLayer renderInContext:context];

        templateImage = UIGraphicsGetImageFromCurrentImageContext();

        UIGraphicsEndImageContext();

This backingLayer has many sublayers added like this, and this view is my subView. But now how can i get the events of the view in the respective UIViews since i have added them as sublayers , i am trying to achieve something like the Flipboard application, where they have the page navigation and click events even though they are sub layers.

Upvotes: 0

Views: 1388

Answers (2)

Johnny Oshika
Johnny Oshika

Reputation: 57512

As claireware mentioned, CALayers don't support event handling directly. However, you can capture the event in the UIView that contains the CALayer and send the UIView's implicit layer a 'hitTest' message to determine which layer was touched. For example:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView:self];
    CALayer *target = [self.layer hitTest:location];
    // target is the layer that was tapped
} 

Here is more info about hitTest from Apple's documentation:

Returns the farthest descendant of the receiver in the layer hierarchy (including itself) that contains a specified point.

Return Value
The layer that contains thePoint, or nil if the point lies outside the receiver’s bounds rectangle.

Upvotes: 1

kamprath
kamprath

Reputation: 2308

The point of CALayers is that they are light weight, specifically not having the event handling overhead. That is what UIView's are for. Your options are to either convert your code to using UIViews for event tracking, or write your own event passing code. For the second one, basically, you would have your containing UIView do a bunch of "is point in rect" queries for each sub-layer's bounds, and pass the event to (a custom method in) the CALayer with the highest z-position.

Upvotes: 2

Related Questions