(一)原理
(1)运行循环监听所有事件。当一个按钮什么的 addTarget 监听了单机事件后,其实也会触发触摸事件。触摸事件是按照UIApplication-->UIWindow-->rootViewController-->view-->button来找到子控件,从而执行addTarget方法的。所以说如果一个view里面又有一个view,单机里面的view,如果调用父类的touchBegin,则两个touchBegin都会调用。第一个收到相应的叫做第一响应者,然后其父控件就是下一个响应者。都是一层层传递的。这一串就叫做响应者链条。
(2)响应都是先去找后添加的。调用hitTest方法来找。hitTest方法返回值是一个UIView,就是说当找到需要的view给系统后就不在继续找了。开始反着传递了。所以说如果在这里修改返回值,可以做出很奇怪的举动。。hitTest就是从UIApplication一直找,知道找到这个触摸view,然后就开始调用touchBegin往下传递了。就是先从下往上找,再从上往下传递。
(二)不接受用户交互的情况:
(1)userInterActionEnable,如果不勾上,就默认不能交互,就直接找父类了。
(2)hidden,隐藏后,就不执行了。
(3)透明度alpha 是0-0.01,就无法交互。
(4)clipSubView裁剪。子控件的view本身在父控件里,所以就算超出了父控件,也不会交互。
(三)测试:hitTest手动调用的时候会有一个返回值,一般return 父类的这个方法。 下面在View中创建两个互不相干的viewA和viewB。然后单击A,检查事件传递。
主view:
#import "MyView.h"@implementation MyView-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { NSLog(@"hitViewMyView"); return [super hitTest:point withEvent:event];}-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event { NSLog(@"touchMyView");}@end
子view1和2
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { NSLog(@"hitViewB"); return [super hitTest:point withEvent:event];}-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event { NSLog(@"touchB");}
实现效果:
结论得知:先从下往上调用hit方法,整个执行2次。然后当找到触摸view的时候调用touchBegin方法。