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

相关推荐
库奇噜啦呼15 分钟前
【iOS】RunLoop学习
学习·ios
黑科技iOS上架2 小时前
iOS应用周末提交什么情况算卡审
经验分享·ios
zzb15804 小时前
ios基础-MVC-UIView
ios·mvc·cocoa
kingbal4 小时前
Flutter:Flutter SDK版本管理工具FVM
android·flutter·ios·android-studio·window
他们都不看好你,偏偏你最不争气20 小时前
【iOS】Runtime - Part 2 && 消息发送:缓存、查找与转发
macos·ios·objective-c·cocoa
2501_915918411 天前
iOS App性能测试工具的实现方法与优化循环指南
android·ios·小程序·https·uni-app·iphone·webview
他们都不看好你,偏偏你最不争气1 天前
【iOS】Runtime - Part 1 && 对象与类的本质
macos·ios·objective-c·cocoa
黑科技iOS上架1 天前
Swift6.0多线程特性注意事项
ios