事件处理和手势识别

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

  • 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,手势也有代理的方法。

你可能感兴趣的:(事件处理和手势识别)