关于响应链的一些研究成果#
关于响应链的一些研究成果#
假设我们有一个VC1,VC1上面加盖一个View0 和 View1,点击VC跳转进VC2; 现在的需求是:点击View0不跳转,但是点击View1跳转
1、在View0的子类实现如下方法即可:
//hitTest:withEvent: 和 touchesBegan:withEvent:混用,可以实现强行阻断点击事件的响应链
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
if (CGRectContainsPoint(self.frame, point)) {
return self;
}else{
return nil;
}
}
//如果不进行混用,也就是说只实现hitTest:withEvent:而不实现touchesBegan:withEvent:无效
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSLog(@"");
}2、如果需要截断View1的事件响应,那么在View1里面实现
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSLog(@"");
}以上代码亲测有效
科普在前
1、首先产生了事件之后,系统会把事件打包成event,交给application,然后传递给window,从大到小的锁定,锁定是哪个view产生的事件,这一条链就是通过hitTest
2、锁定了之后,就看这个view能否响应,如果不能,就按照之前的那条链往上询问,能否响应就是走的touchBegin
3、手势本质来讲就是对touch的封装,但是默认情况下手势会禁止touchBegin的响应
4、如果要打开,手势有一个属性,BOOL类型,可以让手势和touch的那一套方法共存子视图超出父视图的解决方案 :在父视图里面写
-(UIView *)hitTest:(CGPoint)point
withEvent:(UIEvent *)event{
UIView *view = [super hitTest:point
withEvent:event];
if (!view) {
//将坐标由当前视图发送到 指定视图 fromView是无法响应的范围小父视图
CGPoint stationPoint = [self.delBtn convertPoint:point
fromView:self];
if (CGRectContainsPoint(self.delBtn.bounds, stationPoint)){
view = self.delBtn;
}
}return view;
}