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 方法

相关推荐
库奇噜啦呼35 分钟前
【iOS】音频与视频播放
ios·音视频·cocoa
大熊猫侯佩8 小时前
黑衣人档案:用 Apple Foundation Models + SwiftUI 打造 AI 聊天机器人全攻略
ios·swiftui·ai编程
大熊猫侯佩8 小时前
侠客行・iOS 26 Liquid Glass TabBar 破阵记
ios·swiftui·swift
2501_9160074710 小时前
手机使用过的痕迹能查到吗?完整查询指南与步骤
android·ios·智能手机·小程序·uni-app·iphone·webview
從南走到北11 小时前
JAVA国际版同城外卖跑腿团购到店跑腿多合一APP系统源码支持Android+IOS+H5
android·java·ios·微信小程序·小程序
alengan14 小时前
苹果企业签名流程
ios·iphone
Digitally1 天前
如何在Mac上同步iPhone短信
macos·ios·iphone
2501_915106321 天前
App HTTPS 抓包 工程化排查与工具组合实战
网络协议·ios·小程序·https·uni-app·php·iphone
2501_916008891 天前
金融类 App 加密加固方法,多工具组合的工程化实践(金融级别/IPA 加固/无源码落地/Ipa Guard + 流水线)
android·ios·金融·小程序·uni-app·iphone·webview
2501_915921431 天前
Fastlane 结合 开心上架(Appuploader)命令行版本实现跨平台上传发布 iOS App 免 Mac 自动化上架实战全解析
android·macos·ios·小程序·uni-app·自动化·iphone