條件:
ViewA 點(diǎn)擊動(dòng)作執(zhí)行的是NSLog(@"111");
ViewB 點(diǎn)擊動(dòng)作執(zhí)行的是NSLog(@"222");
ViewC 點(diǎn)擊動(dòng)作執(zhí)行的是NSLog(@"333");
ViewC是ViewB的子視圖
Q:點(diǎn)擊ViewC超出ViewB的范圍的區(qū)域會(huì)打印什么孝治?
***這里涉及的知識(shí)是響應(yīng)鏈≌铗龋可以看看 http://www.reibang.com/p/09ea3fff3ffd
1.工作流程
調(diào)用hitTest:withEvent:/pointInside:withEvent:
查找點(diǎn)擊的點(diǎn)在哪個(gè)視圖上吓妆,如果有子視圖邻吭,就查找全部子視圖狱意,看看在哪個(gè)子視圖的范圍內(nèi)躲株。找到它汉匙,看看能不能響應(yīng)這個(gè)事件稿黍,如果不能響應(yīng)就往上傳遞疹瘦。
UIApplication->UIWindow->ViewA->ViewB->ViewC
正常來(lái)說(shuō)應(yīng)該打印的是333,結(jié)果打印的是111。
如果點(diǎn)擊在B上 巡球,hitTest:withEvent返回的是ViewB
點(diǎn)擊在B范圍內(nèi)的C上言沐,hitTest:withEvent返回的是ViewC
點(diǎn)擊在B范圍外的C上,酣栈,hitTest:withEvent返回的是nil险胰,也就是說(shuō)沒(méi)找到C上,所以就直接找到了A矿筝,現(xiàn)象就是 點(diǎn)擊在B范圍外的C上起便,輸出的就是11111111111~~~。
2.解決方法
如果ViewB執(zhí)行hitTest:withEvent返回的是nil,就查找是不是真的不在它的子視圖上榆综,如果查到在子視圖上就返回子視圖
重寫(xiě)ViewB的hitTest:withEvent方法妙痹,據(jù)說(shuō)重寫(xiě)pointInside:withEvent:這個(gè)也可以
- (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;
}
萬(wàn)事大吉,趕緊試試吧鼻疮!