lALO1gkBss0IoM0E2g_1242_2208.png_620x10000q90g.jpg
條件:
ViewA 點擊動作執行的是NSLog(@"111");
ViewB 點擊動作執行的是NSLog(@"222");
ViewC 點擊動作執行的是NSLog(@"333");
ViewC是ViewB的子視圖
Q:點擊ViewC超出ViewB的范圍的區域會打印什么?
***這里涉及的知識是響應鏈。可以看看 http://www.lxweimin.com/p/09ea3fff3ffd
1.工作流程
調用hitTest:withEvent:/pointInside:withEvent:
查找點擊的點在哪個視圖上,如果有子視圖,就查找全部子視圖,看看在哪個子視圖的范圍內。找到它,看看能不能響應這個事件,如果不能響應就往上傳遞。
UIApplication->UIWindow->ViewA->ViewB->ViewC
正常來說應該打印的是333,結果打印的是111。
如果點擊在B上 ,hitTest:withEvent返回的是ViewB
點擊在B范圍內的C上,hitTest:withEvent返回的是ViewC
點擊在B范圍外的C上,,hitTest:withEvent返回的是nil,也就是說沒找到C上,所以就直接找到了A,現象就是 點擊在B范圍外的C上,輸出的就是11111111111~~~。
2.解決方法
如果ViewB執行hitTest:withEvent返回的是nil,就查找是不是真的不在它的子視圖上,如果查到在子視圖上就返回子視圖
重寫ViewB的hitTest:withEvent方法,據說重寫pointInside:withEvent:這個也可以
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *view = [super hitTest:point withEvent:event];
if (view == nil) {
for (UIView *subView in self.subviews) {
CGPoint tp = [subView convertPoint:point fromView:self];
if (CGRectContainsPoint(subView.bounds, tp)) {
view = subView;
}
}
}
return view;
}
萬事大吉,趕緊試試吧!