您好,欢迎来到二三娱乐。
搜索
您的当前位置:首页iOS 事件处理

iOS 事件处理

来源:二三娱乐

 iOS事件分类:

1. 触摸事件  

 - 手指点击,滑动,拖拽,捏合等都属于触摸事件

2. 加速计事件

- 手机摇晃等事件

3. 远程控制事件

- 耳机遥控音乐播放等事件

触摸事件的处理

    在iOS开发中,我们要处理各种各样的事件,但是并不是所有的对象都能处理事件

只有继承自UIResponder的对象才能接受和处理事件。我们称这些对象为“响应者对象”。

    当我们用手指触摸屏幕上的控件(UIView及其子类)时,系统会自动调用View的事件处理方法:

  1. 当手指开始触摸时调用:

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

2. 当手指在控件上移动时调用:

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

3. 当手指离开控件时调用:

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

4. 触摸事件被强制结束,如电话呼入强制切换界面会打断触摸过程,此时系统会调用:

- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event

   以上方法中,系统都会传入两个参数:

1)(NSSet *)touches :这时一个UITouch对象的集合(你用几个手指触摸集合中就有几个UITouch对象)

2)(UIEvent *)event : 触摸产生的事件

  UITouch对象:

1. UITouch对象中保存者跟手指触摸时相关的信息,比如触摸的位置,时间,阶段等

2. 手指在控件上滑动是,UITouch对象会更新自身信息,使之能一直保存手指触摸的位置信息等

3. 当手指离开屏幕时,系统会自动销毁这个UITouch对象

4. 利用UiTouch对象可以获得手指在屏幕上的触摸位置信息,调用一下俩个方法:

- (CGPoint)locationInView:(UIView *)view

这个方法返回当前手指触摸在view上的位置,如果传入的view为空,返回的触摸点为在UIWindow上的位置

- (CGPoint)previousLocationInView:(UIView *)view

这个方法返回的是前一个触摸点的位置

UIEvent对象:

   每产生一个事件,都会产生一个UIEvent对象,这个对象记录了事件产生的事件和类型

     每一个完整的触摸事件,都会经历上面3个状态:

   触摸开始->触摸移动->触摸结束 (->触摸取消)对应:touchbegan ->touchMoved->touchEnded (->touchCancelled)

注意: 

1.每一个完整的触摸过程中只会产生一个事件对象,4个触摸方法都是同一个事件对象

2.如果使用两根手指同时触摸屏幕,(NSSet *)touches中存放两根UITouch对象,并且系统只会调用一次touchBagan:withEvent:方法。

3.如果两根手指一前一后触摸屏幕,(NSSet *)touches中存放一个UITouch对象,并且系统会调用两次touchBagan:withEvent:方法。

事件的传递

事件的传递过程:

1. 发生触摸事件后,系统会将该事件丢到UIAppcation管理的事件队列中(按先入先出方式处理)

2. UIApplication会从事件队列中取出最前面的事件,将事件发送给应用程序主窗口(KeyWindow)

3. 程序主窗口会根据程序视图的层次结构,选出最适合处理该事件的视图来处理触摸事件

     系统选择最适合处理事件的视图的方法:

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

系统会调用这个方法来选择最适合处理事件的视图。 以下是内部实现原理:

     1)判断自己能否处理事件(3个条件:1,能否和用户交互,UserInteractionEnable为YES  2,控件透明度>=0.01  3,控件hidden属性为YES)

     2)如果自己能处理,则判断触摸点是否在自己身上

     3)如果在自己身上,则遍历本控件的所有子控件,遍历顺序是,从后往前遍历(即后添加的先遍历),如果遍历有子控件,然后子控件重复这三个步骤。

     4)如果没有符合条件的子控件,那么这个控件就是最适合处理事件的控件

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

// 1.判断下能否接收触摸事件

if (self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.0) return nil;

// 2.判断下点在不在控件上

if ([self pointInside:point withEvent:event] == NO) return nil;

// 3.从后往前遍历子控件

int count = (int)self.subviews.count;

for (int i = count - 1; i >= 0 ; i--) {

// 取出显示在最前面的子控件

UIView *childView =  self.subviews[i];

// 转换成子控件坐标系上点

CGPoint childP = [self convertPoint:point toView:childView];

UIView *fitView = [childView hitTest:childP withEvent:event];

if (fitView) {

return fitView;

}

// 表示没有比自己更合适的view

}

return self;

}

我们一般可以是用这个方法来拦截事件传递。

4.找到视图控件后,系统就会调用控件的touch(4个touch方法)方法来处理事件

事件的处理过程:

  当系统经过上面的步骤找到最适合处理事件的控件后,就会调用这个控件的touch方法来处理对象。而系统默认情况下,这些touch方法会顺这响应者链条向上传递,将事件移交给上一个响应者处理。

什么是响应者链条?

由多个响应者连接起来的链条。

注: 一个对象可以有多个响应者处理

实现方法:由于系统处理事件时会将事件顺着响应者链条向上传递,因此可以重写下一级的事件处理方法时调用回[super touch...]方法,在上一级再重写处理方法,这样两个响应者都能对这个事件进行处理了。

判断上一级响应者:

1.如果这个控件(view)是控制器的view,那么上一级响应者就是控制器

2.如果这个控件(view)不是控制器的view,那么上一级响应者就是它的父控件

Copyright © 2019- yule263.com 版权所有 湘ICP备2023023988号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务