知识点总结

iOS UI事件的传递机制

2019-04-04  本文已影响4人  飞不越疯人院

日常开发中用到事件传递的场景:

自定义的Tabbar的中间按钮为大的圆形; 预期效果是只让红框内的圆形部分相应点击事件;
文章讲解内容代码示例

image.png
现在的效果是点击了非圆形区域也相应了事件,这明显不是想要的效果 image.png

处理后的效果

image.png

事件传递的主要两个方法:

///最终哪个视图响应事件, 将哪个视图返回;
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    if (self.hidden == YES || self.alpha < 0.01 || self.isUserInteractionEnabled == NO) {//0.01临界值
        return nil;
    }
    if ([self pointInside:point withEvent:event]) {
        __block UIView *view = nil;
        ///遍历当前视图的subviews
        [self.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            ///转换坐标
            CGPoint thePoint = [self convertPoint:point toView:obj];
            ///子视图调用
            view = [obj hitTest:thePoint withEvent:event];
            if (view) {
                *stop = YES;
            }
        }];
        if (view != nil) {
            return view;
        }else {
            return self;
        }
    }else {
        ///点击区域不在当前视图范围内, 不要响应
        return  nil;
    }
}

///判断某个点击位置是否在当前视图内;
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    CGFloat x = point.x;
    CGFloat y = point.y;
    CGFloat centerX = self.center.x;
    CGFloat centerY = self.center.y;
    ///点击点与当前控件中心点距离
    double twoPointOffset = sqrt(pow((x - centerX), 2) + pow(y - centerY, 2));
    ///判断是否在圆形区域内
    if (twoPointOffset <= self.frame.size.width / 2) {
        return YES;
    }
    return NO;
}
 


事件的传递流程:

知识点:倒序遍历, 因为不考虑透明度和frame的因素, 后面添加的会在最上层,理论上也是最先响应;

视图响应流程:

用到的几个方法
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
}

如果点击了View5. 则处理事件流程为:


知识点:如果到了UIApplicationDelegate这一层事件仍然没有被响应处理掉,会出现什么现象?
注意, 程序不会崩溃, 而是会将这个事件丢弃掉;


其他:UIView和Calyer的关系

UIView CALayer
可以响应事件 不能响应事件
UIViewLayerdelegate --
负责处理事件 负责绘制
内部有subviews 内部有subLayers

这种分工方式体现出单一职责原则
某种程度上简单理解为:CALayer+响应链/事件 = UIView;

上一篇下一篇

猜你喜欢

热点阅读