文档章节

UI_04 事件处理

黑伞将军
 黑伞将军
发布于 2015/08/19 21:27
字数 1056
阅读 44
收藏 1

⼀、事件

iOS 有三种事件类型:

  • 触控事件(UIEventTypeTouches):单点、多点触控以及各种手势操作;

  • 传感器事件(UIEventTypeMotion):重力、加速度传感器等;

  • 远程控制事件(UIEventTypeRemoteControl):远程遥控iOS设备多媒体播放等;



⼆、触摸的基本概念

     UIView⽀持触摸事件(因为继承于UIResponder),⽽且⽀持多点触摸。需要定义UIView⼦类,实现触摸相关的⽅法。

事件处理方法

     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

     从方法名字可以知道,他们分别对应了屏幕事件的开始、移动、结束和取消几个阶段,前三个阶段理解都没问题,最后一个取消事件的触发时机是在诸如突然来电话或是系统杀进程时调用。这些方法的第一个参数定义了UITouch对象的一个集合(NSSet),它的数量表示了这次事件是几个手指的操作。第二个参数是当前的UIEvent对象。下图展示了一个UIEvent对象与多个UITouch对象之间的关系。

//1.开始触摸
- (
void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//    NSLog(@"++++touches:%@", touches);
   
NSLog(@"%s", __FUNCTION__);
   
self.backgroundColor = [UIColor randomColor];
   
   
_startPoint = [[touches anyObject] locationInView:self];

}


//2.移动触摸  拖动改变view的位置

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

   
NSLog(@"%s", __FUNCTION__);
   
   
CGPoint currentPoint = [[touches anyObject] locationInView:self];
   
   
CGFloat tx = currentPoint.x - _startPoint.x;
   
CGFloat ty = currentPoint.y - _startPoint.y;
   
//    //第一种平移方式:改变center
//    CGPoint tempCenter = self.center;
//    tempCenter.x += tx;
//    tempCenter.y += ty;
//    self.center = tempCenter;
   
//第二种平移方式:使用transform
   
self.transform = CGAffineTransformTranslate(self.transform, tx, ty);

#pragma mark -- 形变
//    self.transform = CGAffineTransformMakeScale(2, 2);
}

#define fWidth self.window.frame.size.width
#define fHeight self.window.frame.size.height
//3.结束触摸
- (
void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
//    NSLog(@"%.2f, %.2f", self.window.frame.size.height,self.window.frame.size.width);
//   
//    CGFloat x = arc4random()%(int)(fWidth-self.frame.size.width);
//    CGFloat y = arc4random()%(int)(fHeight-self.frame.size.height);
//   
//    self.frame = CGRectMake(x, y, self.frame.size.width, self.frame.size.height);
//   
////    self.center = CGPointMake(x+self.frame.size.width/2, y+self.frame.size.height/2);
//    NSLog(@"%.1f, %.1f", x, y);

}



三、响应者链

响应者

     iOS中所有能响应并处理事件(触摸、晃动、远程事件)的对象都是响应者。响应者是构成响应链和事件传递链的节点。

     系统定义了⼀个抽象的⽗类UIResponder来表⽰响应者。其⼦类都是响应者。

     举个例子,当手指去触摸屏幕上 UIView 的实例对象 aView。触摸的动作会产生一个触摸事件 UIEventTypeTouches,而接收触摸事件的对象 aView,就是一个响应者对象。

     一个事件有可能被多个 responder 接收,第一个接收事件的 responder 就叫 first responder。

     在 iOS 中,几乎所有类都是 responder,比如 UIWindow、UIView、UIControl、UIControllers 等,而这些类都有一个共同的父类 —— UIResponder。UIResponder 声明了用于处理事件的接口,并定义了默认的行为。

     Responder 继承链如下:

响应链

     当一个事件发生时,如果 first responder 不处理,事件就会继续往下传递,被下个 responder 接收,如果下个 responder 也不处理,又会被下下个 responder 接收…… 直到一个 responder 处理了事件或者没有 responder 了。这些 responder 按照传递次序连接起来的链条就构成了响应者链。

     检测到响应者后,实现touchesBegan:withEvent:等⽅法,即处理事件。如果响应者没有处理事件,事件会向下传递。如果没有响应者处理, 则丢弃触摸事件。

  • 响应链:由离用户最近的view向系统传递。 

     initial view –> super view –> …..–> view controller –> window –> AppDelegate –> Application

  • Hit-Testing 链(检测链,与响应链顺序相反):由系统向离用户最近的view传递。 

     UIKit –> active app's event queue –> window –> root view –>……–>lowest view

阻断响应者链

     视图类的属性 : userInteractionEnabled。关闭后能阻断查询过程。

     通过以前的使用发现,label并不能响应事件,其原因是label的userInteractionEnabled属性默认为NO。下面通过向label中添加button控件并设置label的userInteractionEnabled属性使其可以响应事件。

    UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(100, 300, 200, 200)];
    [
self.view addSubview:label];
    [label
release];
   
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.
backgroundColor = [UIColor blackColor];
    button.
frame = CGRectMake(0, 0, 20, 30);
    [button
addTarget:self action:@selector(haha) forControlEvents:UIControlEventTouchUpInside];
    [label
addSubview:button];

    label.userInteractionEnabled = YES;

     可以使用同样的方法设置button.userInteractionEnabled = NO阻断响应链。在此不再演示

http://ryantang.me/blog/2013/12/07/ios-event-dispatch-1/


© 著作权归作者所有

黑伞将军
粉丝 1
博文 33
码字总数 34553
作品 0
张家口
程序员
私信 提问
Android onTouchEvent, onClick及onLongClick的调用机制

针对屏幕上的一个View控件,Android如何区分应当触发onTouchEvent,还是onClick,亦或是onLongClick事件? 在Android中,一次用户操作可以被不同的View按次序分别处理,并将完全响应了用户一...

无鸯
2011/09/08
419
0
Android onTouchEvent, onClick及onLongClick的调用机制

针对屏幕上的一个View控件,Android如何区分应当触发onTouchEvent,还是onClick,亦或是onLongClick事件? 在Android中,一次用户操作可以被不同的View按次序分别处理,并将完全响应了用户一...

丁佳辉
2016/06/16
8
0
android 触摸事件、点击事件的区别

针对屏幕上的一个View控件,Android如何区分应当触发onTouchEvent,还是onClick,亦或是onLongClick事件? 在Android中,一次用户操作可以被不同的View按次序分别处理,并将完全响应了用户一...

eric_zhang
2011/08/08
0
11
浅谈ANR及如何分析解决ANR

一:什么是ANR ANR:Application Not Responding,即应用无响应 二:ANR的类型 ANR一般有三种类型: KeyDispatchTimeout(5 seconds) --主要类型 按键或触摸事件在特定时间内无响应 BroadcastT...

Jerikc
2013/06/13
0
0
EventBus 3.0使用详解

01 前言 当我们进行项目开发的时候,往往是需要应用程序的各组件、组件与后台线程间进行通信,比如在子线程中进行请求数据,当数据请求完毕后通过Handler或者是广播通知UI,而两个Fragment之...

天王盖地虎626
05/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Java基础-Queue

Queue实现 1、没有实现阻塞接口的 LinkedList:实现了java.util.Queue接口和java.util.AbstractQueue接口   内置的不阻塞队列:PriorityQueue和ConcurrentLinkedQueue   PriorityQueue和...

MyOldTime
38分钟前
3
0
阿里云应用高可用 AHAS 正式商用,可一键提升云上应用可用性

在分布式架构环境下,服务间的依赖日益复杂,可能没有人能说清单个故障对整个系统的影响,构建一个高可用的分布式系统面临着很大挑战。 7月17日,阿里云应用高可用服务AHAS 正式商用,包含架...

阿里云云栖社区
41分钟前
2
0
Audio 和 Video的简单介绍

HTML多媒体 , 主要分为Audio 音频和 Video 视频。 1:Audio 基本语法 src 指定当前播放的音频文件,controls播放控制器,loop歌曲循环,autoplay自动播放 (chrome66之后被禁止)主流浏览器已...

凌兮洛
55分钟前
4
0
【iText5 生成PDF】纯Java代码实现生成PDF(自定义表格、文本水印、单元格样式)

工作中遇到需要生成PDF。最终选择了iText。其他也有通过html再生成。感觉不太适合就用了代码实现。 使用iText 5.5.13.1版本。纯Java代码实现 1.自定义表格合并指定行列完成数据填充 2.自定义...

小帅帅丶
56分钟前
11
0
Redis HyperLogLog

关于 Redis HyperLogLog 在说明 HyperLogLog 之前,我们需要先了解一个概念:基数统计。维基百科中的解释是: cardinality of a set is a measure of the “number of elements“ of the set...

xiaomin0322
56分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部