事件传递和响应机制

2019-02-28  本文已影响0人  陌巷先森

iOS中的事件

1.事件的生命周期

事件的生命周期从事件的产生和传递(事件如何从父控件传递到子控件并寻找到最合适的view、寻找最合适的view的底层实现、拦截事件的处理)->事件的响应(找到最合适的view后对事件进行处理,touches方法的重写)

2.事件的分类

iOS中的事件可以分为3大类型:

3.响应者对象(UIResponder)

在iOS中只有继承了UIResponder的对象才能接收和处理事件,UIResponder的子类包括UIView,UIViewController,UIApplication等。响应者接收到原始事件数据,必须处理事件转发到另一个响应者对象,当APP接收到一个事件事,UIKit自动引导事件到最合适的的响应者对象,也叫做第一响应者。
UIResponder内部提供了以下方法来处理事件

触摸事件
- (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;
加速计事件
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event;
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event;
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event;
远程控制事件
- (void)remoteControlReceivedWithEvent:(UIEvent *)event;

4.事件中的概念

在自定义UIView为属性的控件时可以重写触摸事件的方法来进行点击回调。在回调中可以看到方法接收两个参数,一个是UITouch对象的集合,还有一个是UIEvent对象。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    NSLog(@"触摸开始--touches:%@,event:%@",touches,event);
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    NSLog(@"开始移动--touches:%@,event:%@",touches,event);
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    NSLog(@"触摸结束--touches:%@,event:%@",touches,event);
}
//只有在程序强制退出或者来电时才会调用
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{
    NSLog(@"触摸取消--touches:%@,event:%@",touches,event);
}

4.1UIEvent

表示用户交互的事件对象,每产生一个事件,就会产生一个UIEvent对象。在一个用户点击事件处理过程中,UIEvent对象是唯一的。
UIEvent属性如下:

//事件类型
@property(nonatomic,readonly) UIEventType     type NS_AVAILABLE_IOS(3_0);
@property(nonatomic,readonly) UIEventSubtype  subtype NS_AVAILABLE_IOS(3_0);
//事件产生时间
@property(nonatomic,readonly) NSTimeInterval  timestamp;

4.2UITouch

当用户用一根手指触摸屏幕时,会创建一个与手指相关的UITouch对象 ,一根手指对应一个UITouch对象。
UITouch属性如下:

//触摸产生时所处的窗口
@property(nonatomic,readonly,retain) UIWindow *window;
//触摸产生时所处的视图
@property(nonatomic,readonly,retain) UIView *view
;
//短时间内点按屏幕的次数,可以根据tapCount判断单击、双击或更多的点击
@property(nonatomic,readonly) NSUInteger tapCount;
//记录了触摸事件产生或变化时的时间,单位是秒
@property(nonatomic,readonly) NSTimeInterval timestamp;
//当前触摸事件所处的状态
@property(nonatomic,readonly) UITouchPhase phase;

UITouch方法如下:

// 返回值表示触摸在view上的位置
// 这里返回的位置是针对view的坐标系的(以view的左上角为原点(0, 0))
// 调用时传入的view参数为nil的话,返回的是触摸点在UIWindow的位置
(CGPoint)locationInView:(UIView *)view;
// 该方法记录了前一个触摸点的位置
(CGPoint)previousLocationInView:(UIView *)view;

事件的传递和响应

1.事件的产生和传递

1.1事件的产生

1.发生触摸事件后,系统会将该事件加入到一个由UIApplication管理的队列事件中
2.UIApplication会从事件队列中取出最前面的事件,并将事件分发下去以便处理,通常会先发送事件给应用程序的主窗口(keyWindow)
3.主窗口会在视图层次结构中找到一个最合适的视图来处理触摸事件

1.2事件的传递

触摸事件的传递是从父控件传递到子控件。事件传递给窗口或者控件后,就调用hitTest:withEvent:方法寻找更合适的view。方法底层会调用pointInside:withEvent:方法判断点在不在方法调用者的坐标系上,如果返回YES说明点在当前view上,继续通过hitTest:withEvent:方法遍历子控件,直到找到最合适的view。如返回NO,代表事件不在view内,直接返回nil,说明当前view不是最合适的view,其以下的子控件也都会被忽略。
这个方法会忽略以下情况:

2.事件的响应

上一篇下一篇

猜你喜欢

热点阅读