iOS Hittest 机制和实际应用之一 hittest方法

Hittest 机制原理

hitTest的原理就是,当我们点击的时候,会触发 window的

hittest方法,在该方法中会首先使用point inside方法判断

点击的地方是否在window范围内,如果在的话,就倒序遍历姿子视图,然后将point转换为相对于子视图的point,然后在子视图再执行hittest,里面执行同样的流程。如果不在window范围内的话,就返回一个nil

这里写下实现逻辑

复制代码
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
    
    if (self.hidden == NO || self.alpha < 0.05 || self.userInteractionEnabled == NO) {
        //1.当满足这几个条件时,直接丢弃touch事件,不再向下分发。
        return nil;
    }else{
        if (![self pointInside:point withEvent:event]) {
            //2.如果点击point在视图之外,丢弃
            return nil;
        }else{
            //3.分发给子视图
            if (self.subviews.count > 0) {
                for (UIView *subView in self.subviews) {
                    UIView *hitTestSubView = [subView hitTest:point withEvent:event];
                    return hitTestSubView;
                }
            }else{
                return self;
            }
        }
    }
}

实际应用

扩大点击范围

重写 hitTest 方法,通过UIEdgeInsetsInsetRect 方法生成一个新的frame,然后判断point是否在rect里面

复制代码
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
   
    CGRect rect = UIEdgeInsetsInsetRect(self.bounds, self.expandEdgeInset);
    if (CGRectContainsPoint(rect, point)) {
        return self;
    }
    return [super hitTest:point withEvent:event];
}

子视图超出父视图可点击

重写 hitTest 方法 在里面不执行 point inside方法(系统默认是要执行的,因为要判断点击的点是否在自己范围内)

复制代码
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    CGPoint pointInSubbutton = [self convertPoint:point toView:self.subButton];
    if ([self.subButton hitTest:pointInSubbutton withEvent:event]) {
        return [self.subButton hitTest:pointInSubbutton withEvent:event];
    }
    return [super hitTest:point withEvent:event];
}

其实从上面的逻辑来看,不管我们是扩大点击范围,还是子视图超出范围可以点击,

都是去掉了系统hitest方法中的point inside 方法

相关推荐
全栈技术负责人3 小时前
Hybrid应用性能优化实战分享(本文iOS 与 H5为例,安卓同理)
前端·ios·性能优化·html5
Zender Han4 小时前
Flutter 视频播放器——flick_video_player 介绍与使用
android·flutter·ios·音视频
咕噜签名分发冰淇淋6 小时前
苹果ios的系统app应用WebClip免签应用开源及方式原理
ios·开源·cocoa
2501_915106329 小时前
App Store 软件上架全流程详解,iOS 应用发布步骤、uni-app 打包上传与审核要点完整指南
android·ios·小程序·https·uni-app·iphone·webview
开开心心loky9 小时前
[iOS] ViewController 的生命周期
macos·ui·ios·objective-c·cocoa
2501_9160137414 小时前
App 上架全流程指南,iOS App 上架步骤、App Store 应用发布流程、uni-app 打包上传与审核要点详解
android·ios·小程序·https·uni-app·iphone·webview
牛蛙点点申请出战15 小时前
仿微信语音 WaveView 实现
android·前端·ios
TheLittleBoy16 小时前
iOS 26支持的设备列表
ios·ios 26
Magnetic_h16 小时前
【iOS】block复习
笔记·macos·ios·objective-c·cocoa
2501_915918411 天前
Web 前端可视化开发工具对比 低代码平台、可视化搭建工具、前端可视化编辑器与在线可视化开发环境的实战分析
前端·低代码·ios·小程序·uni-app·编辑器·iphone