事件处理标签主要用于了解iOS 中用户和 UI界面交互是靠怎样的机制完成的。
UIResonder
- 只有继承了UIResonder的对象才可以接受并处理事件,这些对象被称为响应者对象。
- UIApplication、- UIViewController、- UIView都继承自UIResponder,因此它们都是响应者对象,都能够接收并处理事件
UIResponder内部提供了以下方法来处理事件:
触摸事件
| 1 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; | 
对于触摸事件,如果想要支持多手指触摸,需要设置一个属性:
上述相应触摸事件的 touches 是一个有UITouch对象的集合。关于 UITouch 的知识请点击UITouch
UIEvent常见属性
- 事件类型1 
 2@property(nonatomic,readonly) UIEventType type; 
 @property(nonatomic,readonly) UIEventSubtype subtype;
- 事件产生的时间1 @property(nonatomic,readonly) NSTimeInterval timestamp; 
加速计事件
| 1 | - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event; | 
远程控制事件
| 1 | - (void)remoteControlReceivedWithEvent:(UIEvent *)event; | 
事件的传递和传递原理
- 第一步: 
 当发生触摸事件后,系统将会将该事件加入到一个由 UIApplication 管理的事件队列中,UIApplication 会从事件队列中取出最前面的事件,发送下去以便处理,通常发送事件给应用程序的主窗口(keyWindow),主窗口会在视图层次结构中找到一个最合适的视图来处理触摸事件。
- 第二步: 
 找到最合适的视图控件后,会调用视图控件的 上述处理事件方法 方法。
示例:
点击了绿色view:
UIApplication -> UIWindow -> 白色 -> 绿色
点击了蓝色的view:
UIApplication -> UIWindow -> 白色 -> 橙色 -> 蓝色
点击了黄色view:
UIApplication -> UIWindow -> 白色 ->橙色 -> 蓝色 ->黄色
如果父控件不能接收触摸事件,那么子控件就不可能接收到触摸事件
一个视图无法接受触摸事件可能是以下三种情况:
- 不接收用户交互- userInteractionEnabled = NO
 
- 隐藏- hidden = YES
 
- 透明- alpha = 0.0 ~ 0.01
 
其中:UIImageView 的 userInteractionEnable 默认时 NO,因此 UIImageView 以及它的子控件默认时不能接受触摸事件的。
事件如何从父控件传递给子控件?(窗口如何找到最合适的视图)
- 首先,判断自己是否能接受触摸事件?
- 然后判断触摸点是不是在自己身上?
- 从外往里遍历子控件,重复前面的两个步骤
当一个视图接受到事件传递时,就会调用 -hitText 方法,这个方法用于判断找出最合适的 view,找到最合适的 view 后就会调用相应的处理方法。
具体代码如下:
| 1 | - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event | 
hitText小练习1
核心代码:
| 1 | 
 | 
练习2
触摸事件的处理(响应者链条)
当事件传递到最合适的 view 上时,系统的默认做法时交给父类去处理。[super touch],将事件顺着响应者链条向上处理,将事件交给上一个响应者处理。
作用:搞清楚响应者链条,可以让一个事件,多个对象处理。响应者对象:继承了UIResonder的可以处理事件的对象。
注意:如果当前 view 是控制器的 view,那么控制器就是上一个响应者。因为控制器也可以处理事件,继承UIResonder,如果当前 view 不是控制器 view,则父控件是上一个响应者。


