事件处理和手势识别

第一篇:事件处理的完整过程

  • 1,在手指触摸屏幕时,会产生一个事件,系统会把这个事件添加到UIApplication管理的事件队列中。
  • 2,取出队列中最前面的事件,交给主窗口Window。
  • 3,主窗口会逐级向上来寻找最适合的视图控件view。
  • 4,找到最适合的view后,这个view就是最适合的响应者。
  • 5,如果这个最适合的响应者不响应事件,那么它就会把这个事件交给它的父控件来响应。
  • 6,如果都不对这个事件作出响应的话,最后还是交给UIApplication来丢弃这个事件。

1,2,3 点是事件的传递过程(寻找最适合的view)
4,5,6 点是事件的响应过程 (完成事件的响应)


建议最后看这个故事

事件的处理过程,为了帮助大家理解,我还是打一个比方,可能不太确切啊O(∩_∩)O哈哈~;我们可以假想这样一个场景:在操场上,有一列学生,一个体育老师面对大家站在前面,和一个来回跑动的班长。
事件的传递过程:
这个时候老师就可以假想成用户,老师发出一个指令:跳十个蛙跳(相当于用户点击了屏幕产生的事件),班长接收到了指令后,就跑到队列的最末尾,由后往前挨个(按照自己的挑选条件)寻找最适合跳这十个蛙跳的人。
事件的响应过程:
找到最适合人选后,班长就把这个指令给了这个同学,叫他跳十个蛙跳,1:要是这个同学比较老实,就跳完十个蛙跳,就结束了,那么这个事件的过程也就都结束了。2:要是这个同学比较爱搞怪,就会自己跳完十个蛙跳后,说叫他后面的那个同学也跳十个(相当于调用了super的响应方法)3:要是这个同学比较牛的话,就会直接说我不跳,叫后面那个跳。
如果事件没有处理完成就会接着这样往下执行下去,直到事件结束。还有可能就是全班的同学都很牛,没有一个人去执行,那么这时候班长也只好默默的把这个指令丢弃掉了。(相当于交给UIApplication来丢弃这个事件。)


过程一:寻找最适合的view

原理:
1.先判断自己是否能够接收触摸事件,如果能再继续往下判断;
2.再判断触摸的当前点在不在自己的身上;
3.如果在自己身上,它会从后往前遍历子控件,遍历出每一个子控件后,重复前面的两个步骤;
4.如果没有符合条件的子控件,那么它自己就是最适合的View。

hitTest 方法底层实现(原理用代码来具体实现)
作 用:当一个事件传递给当前View的时候就会调用这个方法.
    参数:当前手指在屏幕上的点         当前产生的事件
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
1.查看自己能不能接收事件
if(self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01){
return nil; }

2.判断当前的点在不在自己上.
if(![self pointInside:point withEvent:event]){
return nil; }

3.从后往前遍历自己的子控制器.
查看自己是不是最适合的view
int count = (int)self.subviews.count;
for(inti = count -1; i >=0; i--) {
           取出子控制器.
     UIView *childView = self.subviews[i];
          要把当前的点转换成子控件上的坐标点.
     CGPoint  childP = [self  convertPoint:point toView:childView];
     // 这是个递归函数,自己调用自己
     UIView   *view = [childView hitTest:childP withEvent:event];

           如果有值,直接返回,返回的就是最适合的View.
     if (view)
     { return view; }

}

4.没有找到比自己更适合的View.  自己就是最适合的View
return self;

}
上面这段代码是系统自动找出了最合适响应的控件,但我们还可以通过重写下面这两个方法来自己决定谁才是最适合响应的控件。

(可以通过结合使用这两个方法(方法重写)来自己决定谁是最适合响应的控件)
系统方法1:hitTest方法
作用 :寻找最适合的View
参数: 当前手指所在的点 产生的事件
返回值:返回谁, 谁就是最适合的View.
什么时候调用 :只要一个事件,传递给一个控件时, 就会调用这个控件的hitTest 法

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

系统方法2:PointInside方法
作用:判断point在不在方法调用者身上
point:必须是方法调用者的坐标系
什么时候调 :hitTest 方法底层会调用这个方法,判断点在不在控件上.

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{    return YES;
}

过程二:事件的响应

原理:
1.调用最合适控件的touches.... 方法
2.如果调用了[super touches....];就会将事件顺着响应者链条往上传递,传递给上一个响应者
3.接着就会调 上一个响应者的touches.... 方法

ps:
如果最适合响应的view是UIButton控件,那么按钮自己响应事件,就不会调用自己里面的touches...方法了。
如果按钮要调用自己的touches...方法,可以设置按钮不去响应这个事件。

touches.... 方法:
// 刚开始点击时会调用
 - (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 法监听view触摸事件存在一些缺陷
1.必须得自定义view,在自定义的View当中去实现touches... 法.

2.由于是在view内部的touches...方 法中监听触摸事件,因此默认情况下, 无法让其他外界对象监听view的触摸事件
3.不容易区分用户的具体手势 行为(不容易区分是 长按手势,还是缩放手势)这些等

所以iOS 3.2之后,苹果推出了手势识别【UIGestureRecognizer】,在触摸事件处理上大大简化了开发者的开发难度。

二、UIGestureRecognizer 手势识别器
  • 利用UIGestureRecognizer,能轻松识别用户在某个view上面做的一些常见手势
  • UIGestureRecognizer是一个抽象类,定义了所有手势的基本行为,使用它的子类才能处理具体的手势
*********父类UIGestureRecognizer的六个子类*********
UITapGestureRecognizer             点按
UIPinchGestureRecognizer           捏合
UIRotationGestureRecognizer        旋转
UISwipeGestureRecognizer           轻扫
UIPanGestureRecognizer             拖动
UILongPressGestureRecognizer       长按
  • 手势识别的一般步骤:
- 1.实例化手势
- 2.指定手势参数
- 3.将手势附加到指定视图
- 4.编写手势监听方法

三、示例程序:

//1.创建轻扫手势    
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)];    
//2.设定手势的参数  (设置轻扫的方向)  
swipe.direction = UISwipeGestureRecognizerDirectionRight;    
//注意:一个手势,只能对应一个方向.如果想要添加多个方向,就要添加多个手势.    
//3.添加手势.
[self.view addGestureRecognizer:swipe];
//4.实现手势方法.
 - (void)swipe:(UISwipeGestureRecognizer *)swipe
{    

}

注意:

1.一个手势只能对应一个View,但是一个View可以有多个手势。

2.对于多层的view,如果最下面一层的view添加了一个手势,点击上层的view,最下面的这个手势是能识别的。

3.一个手势只能响应一次,如果有两层的view,第一层添加了pan1手势,第二层添加了pan2手势;那么如果滑动第一层,只会执行pan1的方法。这个手势已经响应了一次了,所以第二层不能再次响应了。

4,手势也有代理的方法。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,527评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,314评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,535评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,006评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,961评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,220评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,664评论 3 392
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,351评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,481评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,397评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,443评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,123评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,713评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,801评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,010评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,494评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,075评论 2 341

推荐阅读更多精彩内容