iOS中触摸事件的传递过程
在iOS中,
发生触摸事件后,系统会将该事件加入到一个由UIApplication管理的事件队列中,
UIApplication会从事件队列中取出最前面的事件,并将事件分发下去以便处理,通常,先发送事件给应用程序的主窗口(keyWindow)主窗口根据当前显示的view找出最合适的视图控件,然后调用视图控件处理方法
查找最合适控件是以递归的方式来查找,步骤如下:
1. 看自己能否处理触摸事件,如果不能,事件传递到此结束
2. 触摸点是否在自己身上,如果不在,事件传递到此结束
3. 从后往前遍历子控件,重复前面两步 (因为后加的子控件盖在上面,从后往前可以遍历的次数少点)
4. 如果没有符合条件的子控件,那么就自己最适合处理
自己模拟了一个事件传递的代码,仅供参考
- (UIView *)eventDeliver:(UIView *)view point:(CGPoint)point
{
if(view.isUserInteractionEnabled == YES && view.hidden != YES && view.alpha > 0.01) //是否能接收触摸事件
{
if(CGRectContainsPoint(view.bounds, point)) //触摸点是否在自己身上
{
NSArray *views = view.subviews;
for (NSInteger i = views.count - 1; i >= 0; i--) //从后往前遍历子控件
{
UIView *tempView = views[i];
CGPoint p = [view convertPoint:point toView:tempView]; //转换坐标系
UIView *findOutView = [self eventDeliver:tempView point:p]; //递归查找是否有更合适的子控件
if(findOutView != nil)
{
return findOutView;
}
}
return view; //如果没有符合条件的子控件,那么就返回自己
}
return nil;
}
return nil;
}
最后说一个注意点: 如果父控件不能接收触摸事件,那么子控件就不可能接收到触摸事件, 从上面的示例代码就可以看出