您的位置:首页 > 产品设计 > UI/UE

iOS UIEvent事件及UIResponder响应者

2016-03-15 10:20 323 查看
在iOS中不是所有的对象都能处理事件,只有继承了UIResponder的对象才能接收并处理事件,称之为响应者对象;

UIApplication、UIViewController、UIView都继承自UIResponder,因此它们都是响应者对象,都能接收并处理事件;

UIEvent

是由硬件捕获到的一个表示用户操作设备的对象,事件分为三类:触摸事件、晃动事件、远程控制事件,一个触摸事件包含一个或者多个手指,每个手指是一个UITouch对象;每产生一个事件,就会产生一个UIEvent对象,用于记录事件产生的时刻和类型;

常用属性:

UIEvnetType type;
UIEventSubType subtype;
NSTimeInterval timestamp;


UIResponder

响应者是可以响应用户事件并且可以对其进行处理的对象;UIResponder是响应者的基类,UIApplication、UIView和所有从UIView继承的子类都可以捕获到用户事件(不是所有的类都可以捕获到用户事件);

第一响应者是指当前正在接收事件的响应者对象。要捕获用户事件,需要实现touchesBegan,touchesMoves,touchesEnded等方法;

(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event


用户的触摸操作事件对象存放在touches集合里面,里面存放的是UITouch手指对象;

在上面4个触摸事件处理方法中,都有两个参数,一个完整的触摸过程,会经历3个状态,整个过程中只会产生一个事件对象UIEvent,4个触摸方法都是同一个UIEvent参数;

如果两个手指同时触摸一个view,那么view只会调用1次touchesBegin,参数touches里面有2个UITouch对象;

如果两个手指一前一后分开触摸,则view会分别调用2次touchesBegin,每次调用时的touches参数中只包含1个UITouch对象;

UITouch

表示触摸事件中的一个手指;UITouch支持触摸事件,并且支持多点触摸;

-locationInView:  // 当前手指在所指定的view中的位置
-previousLocationInView:  // 上一次手指在所指定的view中的位置
view  //  所在的view
window  // 所在的窗口对象
tapCount  // 获取手指点击次数


触碰检测(Hit-Test)

通过触碰检测找出Touch事件发生在哪个视图上。递归检测所有的子视图,定位触碰点的位置;当一个触碰事件发生时,从根视图开始,逐个检测判断触碰是否发生在某个子视图上,如果该子视图没有子视图,则事件发生在该视图上;

/**
* 此方法会返回能够处理事件的控件,可以用来拦截所有的触摸事件;
* 如果返回nil,则表示该控件不能处理事件,则事件会向上传递;反之则不会再传递事件;
*/
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
if([self findLink:point]) return self;
return nil;
}

//- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
//{
//    if ([self touchingLinkWithPoint:point]) {
//        return YES;
//    }
//    return NO;
//}


响应者链

由很多响应者链接在一起组合起来的一个链条称之为响应者链条;响应者链定义了iOS中触摸事件的交互规则,如果hit-test检测出的view没有响应事件,事件就沿着响应者链往上传递;如果链中的某个响应者响应了事件或者已经没有响应者了,传递结束;

具体来讲,如果一个UIView没有定义touchesBegan等方法,则事件会向父View传递直到UIViewController的根视图,如果都没有定义事件响应方法,则再一直传递下去直到window,UIApplication,最后丢弃事件;

一次完整的触摸事件的传递响应过程

UIApplication –> UIWindow –> 递归找到最适合处理事件的控件

控件调用touches方法 –> 判断是否实现touches方法 –> 如果没有实现默认会将事件传递给上一个响应者 –> 找到上一个响应者

默认做法是将事件顺着响应者链条向上传递,将事件交给上一个响应者进行处理;

如何判断当前响应者的上一个响应者是谁?

判断当前响应者是否是控制器的view,如果是控制器的view,上一个响应者就是控制器;

如果当前响应者不是控制器的view,上一个响应者就是父控件;

响应者链条作用?

可以让一个触摸事件发生的时候让多个响应者同时响应该事件;通过调用[super touchesXxx];

调整事件传递

对于UIView,将userInteractionEnabled属性设置为NO,或者当视图hidden属性为YES或者alpha为0时,视图也不能接收事件;

对于应用程序来说,可以通过UIApplication的beginIgnoringInteractionEvents和endIgnoringInteractionEvnets来关闭或者开启事件传递;

多点触摸

在UIView中将multipleTouchEnabled属性设置为YES;如果多点触摸已经打开,则在touches和UIEvent中则会存在多个UITouch对象,否则在touches中只会有一个UITouch对象。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ios UIEvent