美文网首页
事件传递

事件传递

作者: 王小宾 | 来源:发表于2016-06-04 13:38 被阅读48次
    屏幕快照 2016-05-25 上午11.01.37.png
    屏幕快照 屏幕快照 2016-05-25 上午11.02.49.png

    最合适响应view:当点击一个view时,她首先将事件传递给UIApplication, UIApplication->UIWindow->控制器view->父视图->子视图->点击view
    touches方法的默认做法是将事件顺着响应者链条向上传递,将事件交给上一个响应者进行处理。

    一个View是如何判断自己为最佳处理点击事件的View

    // recursively calls -pointInside:withEvent:. point is in the receiver's coordinate system
    - (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;
    
    // default returns YES if point is in bounds
    - (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event;
    

    - hitTest: withEvent:方法的底层实现

    此底层实现说明了, 一个view的子控件是如何判断是否接收点击事件的.

    此方法返回的View是本次点击事件需要的最佳View

    // 因为所有的视图类都是继承BaseView
    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
    {
    //    NSLog(@"%@--hitTest",[self class]);
    //    return [super hitTest:point withEvent:event];
    
    
        // 1.判断当前控件能否接收事件
        if (self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01) return nil;
    
        // 2. 判断点在不在当前控件
        if ([self pointInside:point withEvent:event] == NO) return nil;
    
        // 3.从后往前遍历自己的子控件
        NSInteger count = self.subviews.count;
    
        for (NSInteger i = count - 1; i >= 0; i--) {
            UIView *childView = self.subviews[i];
    
            // 把当前控件上的坐标系转换成子控件上的坐标系
         CGPoint childP = [self convertPoint:point toView:childView];
    
           UIView *fitView = [childView hitTest:childP withEvent:event];
    
    
            if (fitView) { // 寻找到最合适的view
                return fitView;
            }
    
    
        }
    
        // 循环结束,表示没有比自己更合适的view
        return self;
    
    }
    

    根据以上的实现, 那么我们就可以重写这个方法, 做一些非常规的效果

    此方法返回的View是本次点击事件需要的最佳View

    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
    {
    
        // 当前控件上的点转换到chatView上
        CGPoint chatP = [self convertPoint:point toView:self.chatView];
    
        // 判断下点在不在chatView上
        if ([self.chatView pointInside:chatP withEvent:event]) {
            return self.chatView;
        }else{
            return [super hitTest:point withEvent:event];
        }
    
    }
    

    相关文章

      网友评论

          本文标题:事件传递

          本文链接:https://www.haomeiwen.com/subject/mgqtdttx.html