iOS事件响应控制(一)

简介: iOS事件响应控制

以前遇到一个项目,一个UIImageView对象上面有一个UIButton对象,然而项目的需求需要在点击 button的同时,UIImageView也接收到点击事件,在不使用代理和通知方法的前提下,通过事件响应链的原理,我们也可以很便捷的解决这个问题。


   在处理这个问题之前,我们应该先清楚IOS的事件响应机制到底是个什么样的原理。


首先,这个事件响应的机制是分为两个部分的。


1、先在视图层级关系中找到应该响应事件的那个视图。


这一步是什么意思,其实很简单,就是找到你所触摸点对应的那个最上层的视图,它的工作原理是这样的:当用户发出事件后,会产生一个触摸事件,系统会将该事件加入到一个由UIApplication管理的事件队列中,UIApplication会取出队列中最前面的事件,发消息给UIWindow,然后UIWindow会对其所有子视图调用hitTest:withEvent:这个方法,这个方法会返回一个UIView的对象,这个方法在执行的时候,它会调用当前视图的pointInside:withEvent:这个方法,如果触摸事件在当前视图范围内,pointInside:withEvent:会返回YES,否则会返回NO;如果返回YES,则会遍历当前视图的所有子视图,统统发送hitTest:withEvent:这个消息,如果返回NO,则hitTest:withEvent:方法返回nil;


上面说起来有些绕,其实就是:hitTest:withEvent:方法会一层一层的向上找,若最上层响应的子视图pointInside:withEvent:返回YES,则返回此子视图,如果所有的都返回nil,则返回当前视图本身self。


例如:我们建两个文件,一个继承于UIButton,一个继承于UIImageView,我们在UIImageView里的代码如下:


#import "MyImageView.h"


@implementation MyImageView

- (instancetype)initWithFrame:(CGRect)frame

{

   self = [super initWithFrame:frame];

   if (self) {

       self.backgroundColor=[UIColor redColor];

   }

   return self;

}

//在这里,我们重写了这个方法,让它直接返回自身,而不是继续向下寻找应该响应事件的视图

-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{

   return self;

}


-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

   NSLog(@"点击了Image");

}

然后将他们创建在一个View上:


- (void)viewDidLoad {

   [super viewDidLoad];

   MyImageView * image = [[MyImageView alloc]initWithFrame:CGRectMake(60, 80, 200, 200)];

   MyButton * btn =[UIButton buttonWithType:UIButtonTypeSystem];

   btn.frame=CGRectMake(20, 20, 40, 40);

   [btn setTitle:@"button" forState:UIControlStateNormal];

   [image addSubview:btn];

   [self.view addSubview:image];

   // Do any additional setup after loading the view, typically from a nib.

}

我们运行,点击这个Btn,会打印如下的信息:

image.png


可以证明,在事件视图寻找中,UIImageView我们重写hitTest:withEvent:方法后,切断了寻找链,如果我们这个做:


-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{

   return nil;

}

你会发现,UIImageView也不再接收事件。

目录
相关文章
|
开发工具 iOS开发 git
iOS开发 - 类似美团选商品页,从按钮上往上滑动,tableview依然响应,点击按钮,按钮也可响应
iOS开发 - 类似美团选商品页,从按钮上往上滑动,tableview依然响应,点击按钮,按钮也可响应
336 0
iOS开发 - 类似美团选商品页,从按钮上往上滑动,tableview依然响应,点击按钮,按钮也可响应
|
iOS开发
iOS开发 - touchBegan事件判断点击的位置在View上还是在View的子View上
iOS开发 - touchBegan事件判断点击的位置在View上还是在View的子View上
448 0
iOS开发 - touchBegan事件判断点击的位置在View上还是在View的子View上
|
Android开发 iOS开发
关于监听微信浏览器返回按钮事件处理安卓IOS通用
关于监听微信浏览器返回按钮事件处理安卓IOS通用
634 0
关于监听微信浏览器返回按钮事件处理安卓IOS通用
|
iOS开发
iOS之UIPickerView滚动事件
在开发中,我们会用到pickerview滚动条,那如何监听到pickview的滚动事件呢,之前开发就遇到过一个问题,快速滑动秒选确定按钮,地址显示不对的问题,解决办法为在点选确定辅助按钮的时候判断当时的pickerView是否正在滚动,如果在滚动则不允许触发点选确定后的其他操作。
541 0
iOS之UIPickerView滚动事件
|
iOS开发
iOS开发- runtime基本用法解析和用runtime给键盘添加工具栏和按钮响应事件
iOS开发- runtime基本用法解析和用runtime给键盘添加工具栏和按钮响应事件
237 0
|
测试技术 定位技术 开发工具
支付交易风险控制小知识:iOS设备限制境外交易
支付交易风险控制小知识:iOS设备限制境外交易
603 0
支付交易风险控制小知识:iOS设备限制境外交易
|
算法 iOS开发
iOS视图滚动的时候控制导航条标题及公告视图的alpha(显示与隐藏)
iOS视图滚动的时候控制导航条标题及公告视图的alpha(显示与隐藏)
356 0
iOS视图滚动的时候控制导航条标题及公告视图的alpha(显示与隐藏)
|
开发框架 开发工具 iOS开发
iOS开发封装一个可以响应超链接的label——基于RCLabel的交互扩展(二)
iOS开发封装一个可以响应超链接的label——基于RCLabel的交互扩展
325 0
iOS开发封装一个可以响应超链接的label——基于RCLabel的交互扩展(二)
|
iOS开发
iOS事件响应控制(二)
iOS事件响应控制
182 0
iOS事件响应控制(二)