手势识别——Gesture Recognizer

iOS目前支持的手势识别

UITapGestureRecognizer(点按)

UIPinchGestureRecognizer(捏合)

UIPanGestureRecognizer(拖动)

UISwipeGestureRecognizer(轻扫)

UIRotationGestureRecognizer(旋转)

UILongPressGestureRecognizer(长按)

 

提示:目前游戏中的手势识别使用的不多

 

手势识别的状态

typedef NS_ENUM(NSInteger, UIGestureRecognizerState) {

    // 没有触摸事件发生,所有手势识别的默认状态

    UIGestureRecognizerStatePossible,

    // 一个手势已经开始但尚未改变或者完成时

    UIGestureRecognizerStateBegan,

    // 手势状态改变

    UIGestureRecognizerStateChanged,

    // 手势完成

    UIGestureRecognizerStateEnded,

    // 手势取消,恢复至Possible状态

    UIGestureRecognizerStateCancelled, 

    // 手势失败,恢复至Possible状态

    UIGestureRecognizerStateFailed,

    // 识别到手势识别

    UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded

};

提示:UITapGestureRecognizer也被称为离散手势,该手势识别不会被取消,只是调用一次selector任务

 

手势识别的属性

state——手势状态

view——手势发生视图

常用方法

locationInView 获得手势发生对应视图所在位置

translationInView 相对于起始位置在视图中的平移位置

 

#import "ViewController.h"

#define kImageInitFrame CGRectMake (10, 130, 300, 196)

@interface ViewController()

@property (weak, nonatomic) UIImageView *imageView;

@end

@implementation ViewController
/*
 手势使用的步骤
 1. 实例化手势
 2. 指定手势参数
 3. 将手势附加到指定视图
 4. 编写手势监听方法
 
 提示:
 1》 imageView默认是不支持用户交互的
 2》 UIGestureRecognizer是一个抽象类,用于自定义手势,不允许直接被实例化
 
 */

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    [self.view setBackgroundColor:[UIColor lightGrayColor]];
    
    // 0. 将imageView添加到视图
    UIImage *image = [UIImage imageNamed:@"001.jpg"];
    UIImageView *imageView = [[UIImageView alloc]initWithImage:image];
    [imageView setFrame:kImageInitFrame];
    [self.view addSubview:imageView];
    
    // imageView默认是不支持用户交互的
    [imageView setUserInteractionEnabled:YES];
    self.imageView = imageView;
    
    // 1. 点按手势
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)];
    // 点按次数,例如双击2
    // 注意:在iOS中最好少用双击,如果一定要用,就一定要有一个图形化的界面告知用户可以双击
    [tap setNumberOfTapsRequired:2];
    // 用几根手指点按
    [tap setNumberOfTouchesRequired:1];
    
    [imageView addGestureRecognizer:tap];
    
    // 2. 长按手势 Long Press
    UILongPressGestureRecognizer *longTap = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longTap:)];
    [imageView addGestureRecognizer:longTap];
    
    // 3. 拖动手势 Pan
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(pan:)];
    [imageView addGestureRecognizer:pan];
    
    // 4. 旋转手势 Rotation
    UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(rotation:)];
    [imageView addGestureRecognizer:rotation];
    
    // 5. 缩放(捏合)手势 Pinch
    UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinch:)];
    [imageView addGestureRecognizer:pinch];
    
    // 6. 轻扫手势 Swipe
    /*
     手指在屏幕上扫动,和拖动手势的区别在于,手指离开屏幕才会触发监听方法
     
     1> 手指可以上、下、左、右四个方向轻轻扫动,如果没有指定方向,默认都是向右扫动
     2> 在设置轻扫手势时,通常需要将手势识别添加到父视图上监听
     3> 在监听方法中,注意不要使用recognizaer.view,因为手势监听的是父视图,而要处理的视图通常是其他的视图
     
     如果要使用多个方向的轻扫手势,需要指定多个轻扫手势,通常只需指定左右两个方向即可。
     
     因为iOS用户大多不习惯上下的轻扫动作
     */
    UISwipeGestureRecognizer *swipe1 = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipe:)];
    [swipe1 setDirection:UISwipeGestureRecognizerDirectionUp];
    [self.view addGestureRecognizer:swipe1];
    
    UISwipeGestureRecognizer *swipe2 = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipe:)];
    [swipe2 setDirection:UISwipeGestureRecognizerDirectionDown];
    [self.view addGestureRecognizer:swipe2];
    
    UISwipeGestureRecognizer *swipe3 = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipe:)];
    [swipe3 setDirection:UISwipeGestureRecognizerDirectionLeft];
    [self.view addGestureRecognizer:swipe3];
    
    UISwipeGestureRecognizer *swipe4 = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipe:)];
    [swipe4 setDirection:UISwipeGestureRecognizerDirectionRight];
    [self.view addGestureRecognizer:swipe4];
}

#pragma mark - 手势监听方法
#pragma mark 轻扫手势
// 尽管轻扫手势也是连续手势,但是该手势是在手指离开屏幕才会被触发的
// 因此,在编写代码时,不需要处理手势的状态
- (void)swipe:(UISwipeGestureRecognizer *)recognizer
{
    // 让图片朝手指不同的方向飞出屏幕,然后再复位
    CGRect frame = kImageInitFrame;
    if (UISwipeGestureRecognizerDirectionUp == recognizer.direction) {
        frame.origin.y -= 400;
    } else if (UISwipeGestureRecognizerDirectionDown == recognizer.direction) {
        frame.origin.y += 400;
    } else if (UISwipeGestureRecognizerDirectionLeft == recognizer.direction) {
        frame.origin.x -= 300;
    } else {
        frame.origin.x += 300;
    }
    
    [UIView animateWithDuration:1.0 animations:^{
        [self.imageView setFrame:frame];
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:1.0f animations:^{
            [self.imageView setFrame:kImageInitFrame];
        }];
    }];
}

#pragma mark 捏合手势
- (void)pinch:(UIPinchGestureRecognizer *)recognizer
{
    /**
     变化过程中,放大缩小
     结束后,恢复
     */
    if (UIGestureRecognizerStateChanged == recognizer.state) {
        [recognizer.view setTransform:CGAffineTransformMakeScale(recognizer.scale, recognizer.scale)];
        
    } else if (UIGestureRecognizerStateEnded == recognizer.state) {
        [UIView animateWithDuration:0.5f animations:^{
            // 恢复初始位置,清除所有的形变效果
            [recognizer.view setTransform:CGAffineTransformIdentity];
        }];
    }
    
}

#pragma mark 旋转手势,至少两根手指
- (void)rotation:(UIRotationGestureRecognizer *)recognizer
{
    // recognizer中的rotation属性是基于图片的初始旋转弧度的
    /**
     变化过程中,旋转
     结束后,恢复
     */
    if (UIGestureRecognizerStateChanged == recognizer.state) {
        [recognizer.view setTransform:CGAffineTransformMakeRotation(recognizer.rotation)];
        /** 
         累加的形变
         */
//        [recognizer.view setTransform:CGAffineTransformRotate(recognizer.view.transform, recognizer.rotation)];
//        // 把手势识别的rotation设置为0,在下一次触发时,以当前的旋转角度为基准继续旋转
//        recognizer.rotation = 0;
    } else if (UIGestureRecognizerStateEnded == recognizer.state) {
        [UIView animateWithDuration:0.5f animations:^{
            // 恢复初始位置,清除所有的形变效果
            [recognizer.view setTransform:CGAffineTransformIdentity];
        }];
    }
}

#pragma mark 拖动手势
- (void)pan:(UIPanGestureRecognizer *)recognizer
{
    NSLog(@"拖动");
    
    /*
     拖动手势结束后,以动画的方式回到初始位置
     */
    // 在手势状态处于“变化”时处理图片的移动
    // UIGestureRecognizerStateChanged类似于touchesMoved方法,会不断地被调用
    if (UIGestureRecognizerStateChanged == recognizer.state) {

        // translationInView,判断在父视图中平移的位置,平移的偏移量始终以视图的初始位置为基础
        CGPoint deltaPoint = [recognizer translationInView:self.view];

        // 用形变参数来改变图像的位置
        [recognizer.view setTransform:CGAffineTransformMakeTranslation(deltaPoint.x, deltaPoint.y)];
        
//        CGRect targetRect = kImageInitFrame;
//        targetRect.origin.x += deltaPoint.x;
//        targetRect.origin.y += deltaPoint.y;
//        
//        [recognizer.view setFrame:targetRect];
    } else if (UIGestureRecognizerStateEnded == recognizer.state) {
        [UIView animateWithDuration:0.5f animations:^{
            // 将图片复位
//            [recognizer.view setFrame:kImageInitFrame];
            [recognizer.view setTransform:CGAffineTransformIdentity];
        }];
    }
}

#pragma mark 长按手势
- (void)longTap:(UILongPressGestureRecognizer *)recognizer
{
    NSLog(@"长按");
    /*
     旋转半圈的动画,动画完成后恢复
     
     长按手势属于连续手势,是需要处理状态
     
     因为长按通常只有一根手指,因此在Began状态下,长按手势就已经被识别了
     
     针对长按的处理,最好放在UIGestureRecognizerStateBegan状态中实现
     */
    if (UIGestureRecognizerStateBegan == recognizer.state) {
        NSLog(@"长按");
        
        [UIView animateWithDuration:1.0f animations:^{
            // 设置动画重复次数
            [UIView setAnimationRepeatCount:4];
            [recognizer.view setTransform:CGAffineTransformMakeRotation(M_PI)];
        } completion:^(BOOL finished) {
            // CGAffineTransformIdentity将视图的形变复原(平移、缩放、旋转)
            [recognizer.view setTransform:CGAffineTransformIdentity];
        }];
    } else if (UIGestureRecognizerStateEnded == recognizer.state) {
//        [UIView animateWithDuration:1.0f animations:^{
//            [recognizer.view setTransform:CGAffineTransformMakeRotation(M_PI)];
//        } completion:^(BOOL finished) {
//            // CGAffineTransformIdentity将视图的形变复原(平移、缩放、旋转)
//            [recognizer.view setTransform:CGAffineTransformIdentity];
//        }];
    }
}

#pragma mark 点按手势
- (void)tap:(UITapGestureRecognizer *)recognizer
{
    NSLog(@"点我了");
    // 做一个动画效果
    // 向下移出屏幕,完成后再重新返回初始位置
    // recognizer.view 就是识别到手势的视图,也就是手势绑定到得视图
    
    CGRect initFrame = recognizer.view.frame;
    CGRect targetFrame = recognizer.view.frame;
    targetFrame.origin.y += 360;
    
    [UIView animateWithDuration:1.0f animations:^{
        // 自动反向重复动画
        [UIView setAnimationRepeatAutoreverses:YES];
        // 设置动画重复次数
        [UIView setAnimationRepeatCount:2];
        
        [recognizer.view setFrame:targetFrame];
    } completion:^(BOOL finished) {
        [recognizer.view setFrame:initFrame];
    }];
}

@end
View Code

 

posted on 2015-07-16 21:12  pTrack  阅读(301)  评论(0)    收藏  举报