前言:在ios编程中,经常会遇到各种复杂的视图,那么我们点击屏幕,是怎么样将点击事件传递到对应的对象上面,延后完成方法的执行的呢?以下已touch事件为例进行说明:
1.Touch事件的传递顺序:
在ios编程中,UIResponer负责事件的管理,因此只有UIResponer的子类才能对事件进行处理,UIApplication, UIViewController,和 UIView均是继承自UIResponer。
window对象总会尝试把响应者设为touch产生的view,通过hit-test来判断。Touch事件会沿着第一响应者(Fist Responder)一直传递到UI Application,如果到最后也不能响应,则被抛弃。
系统如何通过hit-test找到Fist Responder的View
举个例子
点击如图的viewD
通过hit-test来判断触摸在那个view的顺序如下
每一次hit-test通过两个函数实现。
调用pointInside:withEvent: 返回改触摸点是否在View中,hitTest:withEvent:返回触摸点所在的View,然后递归检查起subview
所以,可以通过重写pointInside:withEvent来限制一个View的部分区域响应视图,关于这个,举例。
#import "TriangleButton.h"
@interface TriangleButton()
@property (strong,nonatomic)CAShapeLayer * shapeLayer;
@end
@implementation TriangleButton
-(instancetype)initWithFrame:(CGRect)frame{
if (self = [superinitWithFrame:frame]) {
[selfsetUp];
}
returnself;
}
-(void)setUp{
self.shapeLayer = [CAShapeLayerlayer];
CGMutablePathRef path =CGPathCreateMutable();
CGPathMoveToPoint(path,nil,100,0);
CGPathAddLineToPoint(path,nil,100,100);
CGPathAddLineToPoint(path,nil,0,100);
self.shapeLayer.path = path;
[self.layersetMask:self.shapeLayer];
self.layer.masksToBounds =true;
self.backgroundColor = [UIColoryellowColor];
self.userInteractionEnabled=YES;
UITapGestureRecognizer *tapClick=[[UITapGestureRecognizeralloc]initWithTarget:selfaction:@selector(tapClick_Click)];
[selfaddGestureRecognizer:tapClick];
}
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
if (CGPathContainsPoint(self.shapeLayer.path,nil, point, true)) {
return [superpointInside:point withEvent:event];
}else{
returnfalse;
}
}
-(void)tapClick_Click{
if (self.buttonClick) {
self.buttonClick();
}
}
demo下载地址: https://github.com/changcongcong/TriangleButton