簡介
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ù)雜,適用于一些特殊情況 |