CALayer處理點擊事件

我們知道CALayer不能直接響應任何響應鏈事件,所以不能直接處理點擊事件。但是依然有兩種方法可以幫助我們實現(xiàn)捕捉并且處理CALayer的點擊事件。
運行效果:

運行效果

方法一:convertPoint:

@interface CALayerPointVC ()
@property (nonatomic, strong) CALayer *redLayer;
@property (nonatomic, strong) CALayer *yellowLayer;
@end

@implementation CALayerPointVC

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

- (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];
    CGPoint yellowPoint = [self.yellowLayer convertPoint:point fromLayer:self.view.layer];
    if ([self.redLayer containsPoint:redPoint]) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"point red" message:@"" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
    }
    if ([self.yellowLayer containsPoint:yellowPoint]) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"point yellow" message:@"" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
    }
}

首先使用locationInView方法獲取到點擊在view上的坐標。convertPoint:fromLayer :方法傳入一個CGPoint來轉換坐標系,將在其父圖層上的坐標轉換為相對于圖層自身的坐標,這樣轉換坐標系的方法還有以下幾個:

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

得到觸摸點相對于圖層自身的坐標之后,調用containsPoint:方法。containsPoint:方法傳入一個CGPoint類型參數(shù),如果這個點在圖層的frame內(nèi),則返回YES,否則返回NO。這樣,就實現(xiàn)了對CALayer點擊事件的處理。

方法二: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) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"point red" message:@"" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
    }else if (layer == self.yellowLayer){
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"point yellow" message:@"" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
    }
}

hitTest:同樣傳入一個CGPoint類型參數(shù),但它的返回值不是BOOL類型,而是圖層本身。如果點擊的位置在最外層圖層之外,則返回nil。

使用hitTest:時有一點需要注意:

hitTest:返回的順序嚴格按照圖層樹的圖層順序。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容