判斷點(diǎn)擊、觸摸區(qū)域是否屬于當(dāng)前UIView

簡介

UIView提供了一個(gè)pointInside:withEvent:方法,用于判斷用戶點(diǎn)擊的點(diǎn)是否屬于當(dāng)前這個(gè)視圖,其定義如下:

@interface UIView
// default returns YES if point is in bounds
- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event;
@end

用法示例

比如說美工給我們提供了一張圓形的底色透明的png圖片,如下所示:


?圓形透明圖片.png

現(xiàn)在要求點(diǎn)擊圖片上圓形部分可以觸發(fā)單擊事件,點(diǎn)擊圖片的其它區(qū)域不做任何反應(yīng),這里有2種方案可以實(shí)現(xiàn):

方案1

把圖片做成UIButton,并設(shè)置UIButton的layer.cornerRadius為圓形的半徑:

UIImage *image = [UIImage imageNamed:@"圓形透明圖片.png"];

UIButton *btnView = [UIButton buttonWithType:UIButtonTypeCustom];
[btnView setImage:image forState:UIControlStateNormal];
btnView.frame = CGRectMake(0, 0, image.size.width, image.size.height);
// 設(shè)置UIButton為圓形,并且半徑與圖片半徑一致
btnView.layer.cornerRadius = image.size.width / 2.0;
btnView.clipsToBounds = YES;
[btnView addTarget:self action:@selector(buttonTapped) 
              forControlEvents:UIControlEventTouchUpInside];
方案2

pointInside:withEvent:來實(shí)現(xiàn)
先為UIButton定義一個(gè)擴(kuò)展UIButton (Circle),用于設(shè)置圓形圖片半徑,并重寫pointInside:withEvent:方法

#import <UIKit/UIKit.h>
@interface UIButton (Circle)
// 設(shè)置圖片的圓角半徑
- (void)setCornerRadius:(CGFloat)cornerRadius;
@end


#import "UIButton+Circle.h"
#import "objc/runtime.h"
static char cornerRadiusKey;

@implementation UIButton (Circle)
- (void)setCornerRadius:(CGFloat)cornerRadius
{
    objc_setAssociatedObject(self, &cornerRadiusKey, [NSString stringWithFormat:@"%f", cornerRadius], OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (CGFloat)getCornerRadius
{
    NSString *str = objc_getAssociatedObject(self, &cornerRadiusKey);
    return (str && str.length) ? [str floatValue] : 0;
}
/**
 * 計(jì)算point點(diǎn)與center點(diǎn)的距離,
 * 如果 <= cornerRadius,則表示點(diǎn)擊了圖片的內(nèi)容區(qū)域,視為有有效點(diǎn)擊
 * 如果 > cornerRadius, 則表示點(diǎn)擊了圖片的空白區(qū)域,視為無效點(diǎn)擊
 */
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    CGPoint center = CGPointMake(self.bounds.size.width / 2.0, self.bounds.size.height / 2.0);
    CGFloat distance = sqrt(pow(point.x - center.x, 2) + pow(point.y - center.y, 2));
    return distance <= [self getCornerRadius];
}
@end

下面是使用方式,:

@implementation ViewController
- (void)viewDidLoad
{
    UIImage *image = [UIImage imageNamed:@"圓形透明圖片.png"];
    UIButton *btnView = [UIButton buttonWithType:UIButtonTypeCustom];
    [btnView setImage:image forState:UIControlStateNormal];
    btnView.frame = CGRectMake(100, 100, image.size.width, image.size.height);
    // 設(shè)置半徑
    [btnView setCornerRadius:image.size.width / 2.0];
    [btnView addTarget:self action:@selector(buttonTapped)
                  forControlEvents:UIControlEventTouchUpInside];
   
    [self.view addSubview:btnView];
}
- (void)buttonTapped
{
    NSLog(@"button tapped");
}
@end

運(yùn)行后可以看到:

  • 當(dāng)點(diǎn)擊了圖片內(nèi)容區(qū)域,則會觸發(fā)buttonTapped方法
  • 當(dāng)點(diǎn)擊了圖片的空白區(qū)域,沒有任何反應(yīng)。

總結(jié)

方案1 ?方案2
優(yōu)點(diǎn) 代碼簡單,適用廣 處理比較靈活
缺點(diǎn) 有些特殊情況處理不了 稍顯復(fù)雜,適用于一些特殊情況
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • 好奇觸摸事件是如何從屏幕轉(zhuǎn)移到APP內(nèi)的?困惑于Cell怎么突然不能點(diǎn)擊了?糾結(jié)于如何實(shí)現(xiàn)這個(gè)奇葩響應(yīng)需求?亦或是...
    Lotheve閱讀 59,592評論 51 604
  • 在iOS開發(fā)中經(jīng)常會涉及到觸摸事件。本想自己總結(jié)一下,但是遇到了這篇文章,感覺總結(jié)的已經(jīng)很到位,特此轉(zhuǎn)載。作者:L...
    WQ_UESTC閱讀 6,250評論 4 26
  • -- iOS事件全面解析 概覽 iPhone的成功很大一部分得益于它多點(diǎn)觸摸的強(qiáng)大功能,喬布斯讓人們認(rèn)識到手機(jī)其實(shí)...
    翹楚iOS9閱讀 3,222評論 0 13
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,178評論 25 708
  • 《小飛俠彼得潘》: 一開始還以為是狼叔的那個(gè)彼得潘,原來不是……好吧,搞錯(cuò)了。彼得潘也是被拍爛的一個(gè)題材,很適合小...
    老揚(yáng)閱讀 898評論 0 1

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