事件传递流程:UIApplication-window-self.view-子view
依次向下传递,父视图遍历其子视图检测点击了哪个子控件上,如果点击了子控件就传递给它(子视图在依次检测),如果不能就自己响应。
响应链:
如果hit-test视图(最后一个视图)不处理接收到的事件消息,UIKit将事件转发到响应者链的下一个响应者(抛给父控件或控制器),依次向上抛,如果都没有响应,直接抛弃事件
// 如果子视图不想处理事件(super调用touchesBegan:事件会往上抛给他的父类),如果本视图想处理,在该方法里实现
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
}
例子:btn、红色的view都加在self.view上,btn在最下面,点击红色按钮上面如何让btn响应点击事件
ViewController.m
// 下面的btn
UIButton *btn = [UIButtonbuttonWithType:UIButtonTypeRoundedRect];
[self.view addSubview:btn];
// 红色view
JJRedView *redview = [[JJRedView alloc] init];
redview.btn = btn;
[self.view addSubview:redview];
// 紫色的在红色的上面
JJRedView.h
@interface JJRedView : UIView
@property(nonatomic, retain)UIButton *btn;
@end
JJRedView.m
#import "JJRedView.h"
@implementation JJRedView
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
// 返回能响应点击事件的view
UIView *subview = [super hitTest:point withEvent:event];
if (![self.subviews containsObject:subview]) { //没有点击到子view)
// 判断红色view上的点击范围 在不在btn范围内
//把红色view上的坐标系转成btn的坐标系
CGPoint pp = [self.btn convertPoint:point fromView:self];
// 判断pp点在不在btn范围内
BOOL inbtn = [self.btn pointInside:pp withEvent:event];
if (inbtn) {
return self.btn;
}
}
return subview;
}
@end