Calayer responds to click events

Time:2021-11-29

We know that calayer cannot directly respond to any response chain events, so it cannot directly handle click events. However, there are still two methods to help us capture and process calayer’s click events.

Method 1: convertpoint:
@interface ViewController ()

@property (nonatomic, strong) CALayer *redLayer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
        
    self.redLayer = [CALayer layer];
    self.redLayer.frame = CGRectMake(100, 100, 100, 100);
    self.redLayer.backgroundColor = [UIColor redColor].CGColor;
    [self.view.layer addSublayer:self.redLayer];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    CGPoint point = [[touches anyObject] locationInView:self.view];
    CGPoint redPoint = [self.redLayer convertPoint:point fromLayer:self.view.layer];
    if ([self.redLayer containsPoint:redPoint]) {
        Uialertcontroller * alert = [uialertcontroller alertcontrollerwithtitle: @ "title" message: @ "red" preferredstyle: uialertcontrollerstylealert];
        Uialertaction * action = [uialertaction actionwithtitle: @ "OK" style: uialertactionstyledefault handler: Nil];
        [alert addAction:action];
        [self presentViewController:alert animated:YES completion:nil];
    }
}

use firstlocationInViewMethod to obtain the coordinates of the click on the view.convertPoint: fromLayer :Method to transfer a cgpoint to convert the coordinate system, and convert the coordinates on its parent layer to the coordinates relative to the layer itself. In this way, there are the following methods to convert the coordinate system:

- (CGPoint)convertPoint:(CGPoint)point fromLayer:(CALayer *)layer; 
- (CGPoint)convertPoint:(CGPoint)point toLayer:(CALayer *)layer; 
- (CGRect)convertRect:(CGRect)rect fromLayer:(CALayer *)layer;
- (CGRect)convertRect:(CGRect)rect toLayer:(CALayer *)layer;

After getting the coordinates of the touch point relative to the layer itself, the call is made.containsPoint:method.containsPoint:Method passes in a cgpoint type parameter. If the point is within the frame of the layer, it returns yes, otherwise it returns No. In this way, the processing of calayer click events is realized.

Method 2. Hittest:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    CGPoint point = [[touches anyObject] locationInView:self.view];
    CALayer *layer = [self.view.layer hitTest:point];
    if (layer == self.redLayer) {
        Uialertcontroller * alert = [uialertcontroller alertcontrollerwithtitle: @ "title" message: @ "red" preferredstyle: uialertcontrollerstylealert];
        Uialertaction * action = [uialertaction actionwithtitle: @ "OK" style: uialertactionstyledefault handler: Nil];
        [alert addAction:action];
        [self presentViewController:alert animated:YES completion:nil];
    }
}

hitTest:Similarly, a cgpoint type parameter is passed in, but its return value is not the bool type, but the layer itself. If the clicked position is outside the outermost layer, nil is returned.
usehitTest:There are some points to note when:hitTest:The returned order is strictly in accordance with the layer order of the layer tree.