步骤1:找目标。在iOS视图层次结构中找到触摸事件的最终接受者;
步骤2:事件响应。基于iOS响应者链(Responder Chain)处理触摸事件
在找目标阶段所使用到的两大利器是UIView的 hitTest:withEvent: 以及 pointInside:withEvent: 方法。找目标的过程也称为hit-Testing。先来看一张图(注: 图来自MJ)比较直观:

下面解释一下处理原理:
1、手指触摸屏幕,这个动作被包装成一个UIEvent对象发送给当前活跃的UIApplication (Active Application),Application将该Event对象插到任务队列的末尾等待处理(先进先出,先来的先处理);
2、UIApplication单例将事件发送给APP的主Window(所有显示的view都添加在Window上);
3、主Window调用视图层次结构上逐级使用hit-Testing确认最终的响应目标,这个目标也称为hitTesting view。
在没有做任何重载操作的前提下,系统默认的hit-Testing的处理机制如下:
当前view调用自身的pointInside: withEvent:方法判断触摸点是否在自己范围内:
以上就是第一阶段寻找响应view的机制。这里我们结合一个具体的例子再过一遍(图片引自技术哥的博客):

当用户点击ViewD所在的区域时会进行以下hit-Testing:
这里有几点需要强调:
1、hitTest方法调用pointInside方法;
2、hit-Testing过程是从superView向subView逐级传递,也就是从层次树的根节点向叶子节点传递;
3、遇到以下设置时,view的pointInside将返回NO,hitTest方法返回nil:
hit-Testing过程用代码可以描述如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {    if(self.alpha <= 0.01 || !self.userInteractionEnabled || self.hidden) {        returnnil;    }    BOOLinside = [selfpointInside:point withEvent:event];    UIView *hitView = nil;    if(inside) {        NSEnumerator*enumerator = [self.subviews reverseObjectEnumerator];        for(UIView *subview in enumerator) {            hitView = [subview hitTest:point withEvent:event];            if(hitView) {                break;            }        }        if(!hitView) {            hitView = self;        }        returnhitView;    } else{        returnnil;    }} | 
上一部分我们通过hit-Testing机制找到了hitTesting View,这个hitTesting View就是触摸事件的响应者Responder。在iOS系统中,能够响应并处理事件的对象称之为Responder Object,而UIResponder是所有responder的最顶层基类。当hitTesting view做完自己该做的动作后,可以根据需要将消息传给下一级响应者。那下一级响应者会是什么呢?这取决于iOS中的响应者链Responder Chain,如下图所示:

更具体的:
了解响应者链有时候可以帮我解决一些实际问题。我举个例子,我们知道,当提供给你一个ViewController你可以很容易得到它的view,一句代码的事情:
| 1 | viewWanted = someViewController.view; | 
但如果反过来呢?当给你一个view,让你找到其所在的ViewController呢?这时候响应者链可以帮上忙了,代码如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 | @implementationUIView (FindController)-(UIViewController*)parentController{    UIResponder *responder = [selfnextResponder];    while(responder) {    if([responder isKindOfClass:[UIViewController class]]) {        return(UIViewController*)responder;    }    responder = [responder nextResponder];    }    returnnil;}@end | 
原文:http://www.cnblogs.com/xujiahui/p/6011173.html