GeekBand.iOS-触摸手势

2016/4/11 posted in  iOS学习笔记  

什么是手势

手势是按照特定规律出现的一些列触摸事件,常见手势有以下几种:

  • Tap 轻拍
  • Swipe 单轴滑动
  • Double tap 连续两次轻拍
  • Long press 长按
  • Pinch 捏合手指
  • Two finger tap 双指轻拍
  • Rotate 旋转

实现的原理

  1. 收集一些列的UITouch
  2. 分析是否符合所需要的规律
    • 符合:触发手势响应
    • 否则:转为普通触摸事件响应

Some Example

//Double Tap
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    for(UITouch *aTouch in touches){
        if(aTouch.tapCount >= 2){
            [self respondToDoubleTapFesture:aTouch];
        }
    }
}

//Drag
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch *aTouch = [touches anyObject];
    CGPoint loc = [aTouch locationInView:self];
    CGPpoint preloc= [aTouch previouslocationInView:self];
    
    CGRect myFrame = self.frame;
    float deltaX = loc.x - preloc.x;
    float deltaY = loc.y - preloc.y;
    myFrame.orgin.x += deltaX;
    myFrame.orgin.Y += deltaY;
    [self setFrame:myFrame];
    
}

UIControl

如果所有的手势都需要我们自己来实现,自然的第一加大了开发的任务量,第二其实没有那个必要,毕竟复用率极高。于是,苹果为我们封装了好啦!!

  • UIControl:UIView:UIResponder
  • Traget-Action
  • UIControlEvents
    • TouchDown
    • TouchDownRepeat
    • TouchDragInside
    • TouchDragOutside
    • TouchDragEnter
    • TouchUpInside
    • TouchUpOutside
    • TouchCancel
    • ValueChanged
    • PrimaryActionTriggered
    • EditingDidBegin
    • EditingChanged
    • EditingDidEnd
    • EditingDidEndOnExit
    • AllTouchEvents
    • AllEditingEvents

UIGestureRecongnizer

苹果在ios3.2以后提供的专门处理手势操作的封装。
-initWithTraget:(UIView *)action:(SEL)handleGesture
-[UIView addGestureRecognizer:]

离散手势与连续手势

触控动作同时分为连续动作(continuous)和不连续动作(discrete),连续动作例如滑动和拖拽,它会持续一小段时间,而不连续动作例如单击,它瞬间就会完成,在这两类事件的处理上又稍有不同。对于不连续动作,Gesture Recognizer只会给ViewContoller发送一个单一的动作消息(action message),而对于连续动作,Gesture Recognizer会发送多条动作消息给ViewController,直到所有的事件都结束。

手势识别状态

在事件处理过程中,这两种方式所处的状态又各有不同,首先,所有的触控事件最开始都是处于可用状态(Possible),对应UIKit里面的UIGestureRecognizerStatePossible类,如果是不连续动作事件,则状态只会从Possible转变为已识别状态(Recognized,UIGestureRecognizerStateRecognized)或者是失败状态(Failed,UIGestureRecognizerStateFailed)。例如一次成功的单击动作,就对应了Possible-Recognized这个过程。

如果是连续动作事件,如果事件没有失败并且连续动作的第一个动作被成功识别(Recognized),则从Possible状态转移到Began(UIGestureRecognizerStateBegan)状态,这里表示连续动作的开始,接着会转变为Changed(UIGestureRecognizerStateChanged)状态,在这个状态下会不断循环的处理连续动作,直到动作执行完成变转变为Recognized已识别状态,最终该动作会处于完成状态(UIGestureRecognizerStateEnded),另外,连续动作事件的处理状态会从Changed状态转变为Canceled(UIGestureRecognizerStateCancelled)状态,原因是识别器认为当前的动作已经不匹配当初对事件的设定了。每个动作状态的变化,Gesture Recognizer都会发送消息(action message)给Target,也就是ViewController,它可以根据这些动作消息进行相应的处理。例如一次成功的滑动手势动作就包括按下、移动、抬起的过程,分别对应了Possible-Began-Changed-Recognized这个过程。

同时支持多种手势

  • 用依赖关系改变触发顺序

    -[a requireGestureRecognizerToFail:b];
    b失败之前,a先等待

  • 使用UIGestureRecognizerDelegate控制

    • -gestureRecognizer:shouldReceiveTouch: 这个Touch要不要处理
    • -gestureRecognizerShouldBegin:是否可以响应
    • -gestureRecognizer:ShouldRecognizeSimltaneouslyWithGestureRecognizer: 可以一起触发么?