源码0306-hitText底层实现

//  XMGWindow.m
//  04-事件的产生和传递
#import "XMGWindow.h"

@implementation XMGWindow

// 事件传递的时候调用
// 什么时候调用:当事件传递给控件的时候,就会调用控件的这个方法,去寻找最合适的view
// 作用:寻找最合适的view

// point:当前的触摸点,point这个点的坐标系就是方法调用者
//- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
//{
//    // 调用系统的做法去寻找最合适的view,返回最合适的view
//    UIView *fitView = [super hitTest:point withEvent:event];
//
////    NSLog(@"fitView--%@",fitView);
//
//
//    return fitView;
//}

// 作用:判断当前这个点在不在方法调用者(控件)上
//- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
//{
//    return YES;
//}

//- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
//{
////    NSLog(@"%s",__func__);
//}
// 点击黄色视图 -》 事件 -》 UIApplication -> UIWindow
// 因为所有的视图类都是继承BaseView
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)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;
}

@end
//  BaseView.m
//  04-事件的产生和传递
#import "BaseView.h"

@implementation BaseView

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"%@---touchesBegan",[self class]);
}
// UIApplication -> [UIWindow hitTest:withEvent:] -> whiteView hitTest:withEvent

// 因为所有的视图类都是继承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;

}

@end
时间: 2025-01-13 02:41:53

源码0306-hitText底层实现的相关文章

WebRTC源码入手和底层功能扩展资料分享

?? WebRTC源码入手和底层功能扩展资料分享 "webrtc源码分析群"里有同学说要在源码里加入新功能,想找下有没有相关资料可以分享下,好了解代码框架和入手修改代码,但是相关的资料少之又少,所以我找了相关的资料,希望能对大家有所帮助. WebRTC代码结构: http://blog.sina.com.cn/s/blog_40d608bb01010n73.htmlhttp://www.cnblogs.com/fangkm/p/4370492.htmlhttp://mojiapp.cn

深入源码分析SpringMVC底层原理(二)

原文链接:深入源码分析SpringMVC底层原理(二) 文章目录 深入分析SpringMVC请求处理过程 1. DispatcherServlet处理请求 1.1 寻找Handler 1.2 没有找到Handler的处理 1.3 根据Handler寻找Adapter 1.4 拦截器的处理 1.5 Adapter处理请求 1.6 异常视图的处理 1.7 页面的跳转 2.总结 在上一篇文章中我们讲到了SpringMVC的初始化,分别初始化两个ApplicationContext,并且初始化一些处理器

ConcurrentHashMap源码阅读以及底层实现的简单分析

ConcurrentHashMap 是可以实现多线程并发的HashMap,它是线程安全的. 前面分析过 HashMap的源码,它和HashMap有很多的相同点一样,比如它也有 initialCapacity 以及负载因子 loadFactor 属性.而且他们的默认值也是16和0.75. static final int DEFAULT_INITIAL_CAPACITY =16; static final float DEFAULT_LOAD_FACTOR =0.75f; 和HashMap不同的是

给jdk写注释系列之jdk1.6容器(10)-Stack&amp;Vector源码解析

前面我们已经接触过几种数据结构了,有数组.链表.Hash表.红黑树(二叉查询树),今天再来看另外一种数据结构:栈. 什么是栈呢,我就不找它具体的定义了,直接举个例子,栈就相当于一个很窄的木桶,我们往木桶里放东西,往外拿东西时会发现,我们最开始放的东西在最底部,最先拿出来的是刚刚放进去的.所以,栈就是这么一种先进后出( First In Last Out,或者叫后进先出) 的容器,它只有一个口,在这个口放入元素,也在这个口取出元素. 栈最主要了两个动作就是入栈和出栈操作,其实还是很容易的明白的对不

java集合类源码剖析

java集合类源码剖析 hashmap 底层实现 HashMap.Entry数组,数组+拉链 static class Entry<K,V> implements Map.Entry<K,V> { final K key; V value; Entry<K,V> next; final int hash; } Entry对象代表了HashMap中的一个元素(键值对) hashCode相同(碰撞)的元素将分配到Entry数组的同一个桶中 同一个桶中的Entry对象由nex

Java中arraylist和linkedlist源码分析与性能比较

Java中arraylist和linkedlist源码分析与性能比较 1,简介 在java开发中比较常用的数据结构是arraylist和linkedlist,本文主要从源码角度分析arraylist和linkedlist的性能. 2,arraylist源码分析 Arraylist底层的数据结构是一个对象数组,有一个size的成员变量标记数组中元素的个数,如下图: * The array buffer into which the elements of the ArrayList are sto

Skynet服务器框架(二) C源码剖析启动流程

引言: 之前我们已经完成了在Linux下配置安装 skynet 的环境,并成功启动了 skynet 服务框架,为了从底层更好地理解整个框架的实现过程,我们有必要剖析一下源码,由于底层的源码都是用C语言写的,lua脚本基本是用来进行业务层开发,所以我们从C源码开始解读框架.打开下载包的 skynet-src 目录,这里是skynet框架的核心C源码,接下来我们就要来解读 skynet_main.c 和 skynet_start.c 这两个与skynet启动相关的C源码. 1.入口函数和初始化: 我

Swoft 源码分析系列 - 综述

首个基于 Swoole 原生协程,新时代PHP高性能协程框架,内置 HTTP 服务器,常驻内存,不依赖传统的 PHP-FPM,没有复杂的异步回调.没有繁琐的yield, 有类似 Go 语言的协程.灵活的注解.强大的全局容器.完善的服务治理等等. 基于 Swoole 扩展 内置 HTTP 协程服务器 MVC 分层设计 高性能路由 全局容器注入 灵活的中间件 高性能 RPC 别名机制 事件机制 国际化(i18n) 参数验证器 RESTful支持 服务治理熔断.降级.负载.注册与发现 连接池 Mysq

AQS 框架之 Unsafe 源码详解

■ 前言 之前 LockSupport那篇已经叙述了是线程阻塞工具类,其底层由 Unsafe 实现,即 park(), unpark() 方法,获取指针偏移量,并操纵内存.本篇主要介绍 Unsafe 的源码,看看底层到底做了什么. ■ Unsafe 综述 作用: Unsafe是个后门类,封装了一些类似指针的操作,提供了一些可以直接操控内存和线程的底层操作 使用: Unsafe被JDK广泛用于nio包和并发包中,但是不建议在生产环境使用,风险太大 不安全: 不安全指的是指针的操作不安全(Java因

MyBatis源码解读

前言 之前我们通过图片讲解了Mybatis底层原理,今天我们就从源码入手去解读下Mybatis这个持久化框架是如何执行SQL的这个完整过程. 老样子,我们在看源码之前先写下demo,参考官方文档进行编写即可.mysql5.7\mybatis1.3.9\springboot项目 mybatisdemo User表的model类 package com.ckmike.mybatisdemo.model; import java.util.Date; /** * User 简要描述 * <p> TO