前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >事件分发机制

事件分发机制

作者头像
Mr.RisingSun
发布2018-01-09 18:19:11
9960
发布2018-01-09 18:19:11
举报
文章被收录于专栏:移动端开发移动端开发

前言总结:

    iOS的事件可以大概分为三种类型,我们会对这三种类型分别做一些介绍说明,先总结一下:

    1.  Milti-Touch Events 触控事件:单点、多点、手势。

    2.  Motion Events  传感器事件:重力、加速度。

    3.  Remote Control Events  远程遥控事件。

分别说明:

一:Touch Events 这个是重点,也是需要仔细说的,大家可以先想一下这样的一个过程,你点击一下屏幕,系统怎么找到我们的APP,又是怎样找到我们点击的界面,然后执行了我们的点击事件的。以前比较流行的中间凸起的标签栏,你有具体考虑过中间那个按钮的点击事件吗?超出标签栏那部分的点击事件你要不做处理,它能执行的到吗?

    先说说Touch Events大致的执行过程;

    点击手机屏幕 ----> UIKit 会生成一个 UIEvent事件,把UIEvent分发给当前活跃着的APP ----> 活跃着的APP被告知有事件发生后,UIApplication 单例就从事件队列中取出最新的事件,依靠 hit-Testing 找出并且返回你点击的View,让View执行事件。这样就是一个大概的过程。这里要弄清楚的就是这个hit-Testing了。给一个大概的流程图,明杰老师的;

下面就说说我们这个hit-Testing,在UIView中,有这样两个需要你特别注意的方法;

代码语言:javascript
复制
- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event; 
 // recursively calls -pointInside:withEvent:. point is in the receiver's coordinate system

- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event;  
 // default returns YES if point is in bounds

我们来说一下,说说 hitTest 方法,看着下面这张图我们说,比如说你点击了屏幕中 C 的位置:

    1:点击的位置是在 RootView当中,RootView 收到hitTest消息, 先调用RootView的pointInside:withEvent方法,判断点击的点是不是在RootView中,上面的例子是在RootView中,所以pointInside:withEvent方法返回YES,接下来会遍历 RootView 的子视图 View1 和 View2。

    2:View1 和 View2 都是 RootView 的子视图,都会接收到 hitTest 消息,但记得遍历的顺序是从上到下,所以先判断 View1 界面,这时候调用 View1 的pointInside:withEvent 方法,方法判断点击的点不在 View1 当中,返回 NO,这时候就会接着判断 View2,注意一点,要是这个点在我们的 View1 当中,就不再去判断 View2 了。

    3:调用 View2 pointInside:withEvent ,点击的点在 View2 当中,返回 YES,这时候 View2 就像我们刚开始时候的 RootView 一样,同样的过程去遍历它的子势图 ViewB 和 ViewC,B的 pointInside:withEvent 返回的是 NO,C的 pointInside:withEvent 返回的是YES,注意这时候,C是没有了子视图的了,就不在往下去遍历,这时候的 hitTest 方法返回的View,就使我们的ViewC。

    上面的过程大概就是这样,就遍历找到了点击的视图ViewC,

    做个假如,假如要是点的不是 B 和 C ,则 B和 C 的 pointInside:withEvent 返回的都是NO,这时候View2就会调用自己的 hitTest 方法,并且返回的UIView就是自己 View2。

现实中的应用:

     以前有仿写过闲鱼APP的标签栏,标签的样式看下面的图片,在这里我们就得处理一下中间的发布按钮,要是不做一些处理,你的点击事件在“发布”按钮找出标签栏的部分是没有效果的。

中间这一块的处理代码如下:

代码语言:javascript
复制
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    if (self.isHidden == NO) {
        
        // 将 点击的point的像素位置转换到 中间按钮 中
        CGPoint newPoint = [self convertPoint:point toView:self.plusBtn];
        
        // 如果点击的位置 newPoint 在 按钮的位置当中,就返回 按钮
        if ([self.plusBtn pointInside:newPoint withEvent:event]) {
            
            return self.plusBtn;
        }
        else
        {
            return [super hitTest:point withEvent:event];
        }
    }
    else
    {
        return [super hitTest:point withEvent:event];
    }
}

PS,太小就不放Git上了,想要这个源代码,前面有我Q,加我Q,我发Demo给你。

它还能做的多呢!

上面就是hitTest的一些概念和简单的使用,其实它能做的事还是挺多的,我把自己学习的笔记链接全都整理出来给;

iOS事件分发机制(一) hit-Testing 技术哥

iOS事件分发机制(二)The Responder Chain 技术哥

iOS触摸事件处理

史上最详细的iOS之事件的传递和响应机制

Motion Events  和  Remote Control Events:

    Motion Events ,传感器加速器这两个东西我就不再说我,以前说屏幕方向的时候写过这两个东西,博客里面也有关于他们的许多的链接,我在就直接把那篇博客的链接给出来,有兴趣的可以翻一翻; 屏幕方向该知道的那些事儿

最后这个 Remote Control Events ,额...暂时没有接触过,就不说了,这个可能还得去问度娘。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-09-12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档