事件分发

在iOS中UIApplication、UIView、UIViewController等继承UIResponder的对象可以响应触摸事件。
事件产生之后,会被加入到由UIApplication管理的事件队列里,接下来自UIApplication往下传递,首先会传递给主window,然后按照view的层级结构一层层往下传递。

规律
UIView :如果view是viewController的根view,那么下一个响应者是viewController,否者是super view

UIViewController 如果viewController的view是window的根view,那么下一个响应者是window;如果viewcontroller是另一个viewcontroller模态推出的,那么下一个响应者是viewcontroller;如果viewcontroller的view被add到另一个viewController的根view上,那么下一个viewcontroller的根view

UIWindow: UIWindow的下一个响应者是UIApplication(一般来说是响应者顶端)

手势识别器
当触摸屏幕产生touch事件后,UIApplication会将事件往下分发,如果视图绑定了手势识别器,touch事件会优先传递给绑定在视图上的手势识别器,如果识别出了手势,就会调用创建手势时所绑定的回调方法,并且会取消touch给所绑定的视图。

UIKit的标准控件(button,选择器。。。)一个view上加了单击手势,一个button,优先button的taget-action事件,不去响应单击事件,如果往button上加单击手势,则响应的是单击手势。

代码判断逻辑:

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    if (self.userInteractionEnabled == NO|| self.hidden== YES ||self.alpha<=0.01) return nil;
    //判断触摸点是否在自己范围内
    if ([self pointInside:point withEvent:event] == NO) return nil;

    //遍历所有子视图,查找是否有最合适的视图
    for (NSInteger i=self.subviews.count-1; i>=0; i--) {
        UIView * childView = self.subviews[i];
        //转换到子视图坐标系
        CGPoint childPoint = [self convertPoint:point toView:childView];
        //递归查找是否存在最合适的View
        UIView *fitView = [childView hitTest:childPoint withEvent:event];
        if (fitView) {
            return fitView;
        }
    }
    return self;
}

你可能感兴趣的:(事件分发)