iOS触摸事件和手势

  • 在ios中,触摸表示当用户手指触击屏幕及在屏幕上移动时,系统不断发送给应用程序的对象。一个UITouch 对象表示一个触摸,一个UIEvent对象表示一个事件。

    例如:捏合手势有两个触摸,两个手指在屏幕上以相反的方向相对的方向,同时也有一个手指操作的简单手势,例如:单击,双击,拖动和滑动,应用程序也有可能处理复杂的手势。
    
  • 手势是指从一个或多个手指接触屏幕开始,直到手指离开屏幕为止发生的所有事情。 手势是触摸事件的集合。

    iOS 系统在 3.2 以后,他提供了一些常用的手势(UIGestureRecognizer 的子类),开发者可以直接使用他们进行手势操作。
    • UIPanGestureRecognizer(拖动)
    • UIPinchGestureRecognizer(捏合)
    • UIRotationGestureRecognizer(旋转)
    • UITapGestureRecognizer(点按)
    • UILongPressGestureRecognizer(长按)
    • UISwipeGestureRecognizer(轻扫)
    另外,可以通过继承 UIGestureRecognizer 类,实现自定义手势(手势识别器类)。

手势状态枚举如下:
typedef NS_ENUM(NSInteger, UIGestureRecognizerState) {
UIGestureRecognizerStatePossible, // 尚未识别是何种手势操作(但可能已经触发了触摸事件),默认状态
UIGestureRecognizerStateBegan, // 手势已经开始,此时已经被识别,但是这个过程中可能发生变化,手势操作尚未完成
UIGestureRecognizerStateChanged, // 手势状态发生转变
UIGestureRecognizerStateEnded, // 手势识别操作完成(此时已经松开手指)
UIGestureRecognizerStateCancelled, // 手势被取消,恢复到默认状态
UIGestureRecognizerStateFailed, // 手势识别失败,恢复到默认状态
UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded // 手势识别完成,同UIGestureRecognizerStateEnded
};

iOS中的手势有

• 单击(Tap)点击作为最常用手势
• 拖动(Drag)
• 滑动(Flick)
• 横扫(Swipe)
• 双击(Double Tap)
• 放大(Pinch)
• 缩小(Pinch)
• 长按(Touch Hold)
父类手势 UIGestureRecognizer
     初始化方法:
     - (instancetype)initWithTarget:(nullable id)target action:(nullable SEL)action NS_DESIGNATED_INITIALIZER;

     给手势添加事件和移除事件
     - (void)addTarget:(id)target action:(SEL)action; 
     - (void)removeTarget:(nullable id)target action:(nullable SEL)action;

获取操作的点

可以通过 locationInView: 获取操作到的点

- (void)rightSwipeGesture:(UISwipeGestureRecognizer *)sender {
    // 获取手势操作到的点
    CGPoint point = [sender locationInView:self.view];
    // 进行判断 是否在指定区域内操作手势
    if (CGRectContainsPoint(CGRectMake(0, 0, self.view.frame.size.width/5, self.view.frame.size.height), point))
    {

        // 在指定区域内做你想做的事
        self.hiddenEnable = YES;
        self.showSlider(YES);

    }
}

UITouch类中包含如下成员函数:
- (CGPoint)locationInView:(UIView *)view:函数返回一个CGPoint类型的值,表示触摸在view这个视图上的位置,这里返回的位置是针对view的坐标系的。调用时传入的view参数为空的话,返回的时触摸点在整个窗口的位置。

CGRectContainsPoint :一个点是否包含在矩形中


Demo 如下:

import "ViewController.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *alertView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    /*
     UIGestureRecognizer

     父类手势带给的东西
     初始化方法:
     - (instancetype)initWithTarget:(nullable id)target action:(nullable SEL)action NS_DESIGNATED_INITIALIZER;

     给手势添加事件和移除事件
     - (void)addTarget:(id)target action:(SEL)action; 
     - (void)removeTarget:(nullable id)target action:(nullable SEL)action;

     */

    //添加单击手势
    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(sigleTapAction:)];
    [self.view addGestureRecognizer:singleTap];

    //双击
    UITapGestureRecognizer *doubelTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubelTapAction:)];
    doubelTap.numberOfTapsRequired = 2;
    [self.view addGestureRecognizer:doubelTap];

    //父类提供的方法:单击要执行必须双击失效
    [singleTap requireGestureRecognizerToFail:doubelTap];

    // 长按手势
    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressAction:)];
    [_alertView addGestureRecognizer:longPress];

    //捏合手势
    UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinchAction:)];
    [_alertView addGestureRecognizer:pinchGesture];

    //拖拽
    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];
    [_alertView addGestureRecognizer:panGesture];

    //旋转
    UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotationAction:)];
    [_alertView addGestureRecognizer:rotationGesture];
    //捏合,旋转要失效
    [pinchGesture requireGestureRecognizerToFail:rotationGesture];

    //左横扫
    UISwipeGestureRecognizer *leftSwipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeAction:)];
    leftSwipeGesture.direction = UISwipeGestureRecognizerDirectionLeft;
    [self.view addGestureRecognizer:leftSwipeGesture];

    //右横扫
    UISwipeGestureRecognizer *rightSwipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeAction:)];
    rightSwipeGesture.direction = UISwipeGestureRecognizerDirectionRight;
    [self.view addGestureRecognizer:rightSwipeGesture];

    //上横扫
    UISwipeGestureRecognizer *upSwipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeAction:)];
    upSwipeGesture.direction = UISwipeGestureRecognizerDirectionUp;
    [self.view addGestureRecognizer:upSwipeGesture];

    //下横扫
    UISwipeGestureRecognizer *downSwipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeAction:)];
    downSwipeGesture.direction = UISwipeGestureRecognizerDirectionDown;
    [self.view addGestureRecognizer:downSwipeGesture];
}
//单击
-(void)sigleTapAction:(UITapGestureRecognizer *)sender{
    NSLog(@"你单击了我!");
    //改变背景颜色
    if (sender.view.backgroundColor == [UIColor whiteColor]) {
        sender.view.backgroundColor = [UIColor blackColor];
    }else{
        sender.view.backgroundColor = [UIColor whiteColor];
    }
}
//双击
-(void)doubelTapAction:(UITapGestureRecognizer *)sender{
    NSLog(@"双击");
}
//长按
-(void)longPressAction:(UILongPressGestureRecognizer *)sender{
    NSLog(@"长按");
    //长按结束出现提示框
    if (sender.state == UIGestureRecognizerStateEnded) {
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"标题" message:@"选择图片" preferredStyle:UIAlertControllerStyleActionSheet];
        UIAlertAction *pAction = [ UIAlertAction actionWithTitle:@"相机" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nullable action){
            NSLog(@"调用本地相机");
        }];
        [alertController addAction:pAction];

        UIAlertAction *photoAction = [ UIAlertAction actionWithTitle:@"相册" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nullable action){
            NSLog(@"调用本地相册");
        }];
        [alertController addAction:photoAction];

        UIAlertAction *cancelAction = [ UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nullable action){
            NSLog(@"cancel");
        }];
        [alertController addAction:cancelAction];

        [self presentViewController:alertController animated:YES completion:nil];


    }
}
//缩放
-(void)pinchAction:(UIPinchGestureRecognizer *)sender{
    sender.view.transform = CGAffineTransformMakeScale(sender.scale, sender.scale);
}
//拖拽
-(void)panAction:(UIPanGestureRecognizer *)sender{

    /********** 拖拽方式一:中心拖拽 *******************
    //当你的状态不等于结束状态  不等以失败状态
    if (sender.state != UIGestureRecognizerStateEnded && sender.state != UIGestureRecognizerStateFailed) {
        CGPoint location = [sender locationInView:sender.view.superview];
        sender.view.center = location;
    }
    */


   /********** 拖拽方式二:一点点的拖拽 ******************
    //当手势按在视图上面的点,转为父系坐标  //拿到中心点
    CGPoint translatedPoint = [sender translationInView:self.view];

    CGFloat firstX;
    CGFloat firstY;

    if([sender state] == UIGestureRecognizerStateBegan) {
        firstX = [sender.view center].x;
        firstY = [sender.view center].y;
        translatedPoint = CGPointMake(firstX+translatedPoint.x, firstY+translatedPoint.y);
        [sender.view setCenter:translatedPoint];
    }
    */

    /********** 拖拽方式三:带惯性的拖拽,向拖拽方向滑动 ******************/
    //视图前置操作
    [sender.view.superview bringSubviewToFront:sender.view];

    CGPoint center = sender.view.center;
    CGFloat cornerRadius = sender.view.frame.size.width / 2;
    CGPoint translation = [sender translationInView:self.view];
    //NSLog(@"%@", NSStringFromCGPoint(translation));
    sender.view.center = CGPointMake(center.x + translation.x, center.y + translation.y);
    //防止抖动
    [sender setTranslation:CGPointZero inView:self.view];
    //动画效果

    if (sender.state == UIGestureRecognizerStateEnded) {
        //计算速度向量的长度,当他小于200时,滑行会很短
        CGPoint velocity = [sender velocityInView:self.view];
        CGFloat magnitude = sqrtf((velocity.x * velocity.x) + (velocity.y * velocity.y));
        CGFloat slideMult = magnitude / 200;
        //NSLog(@"magnitude: %f, slideMult: %f", magnitude, slideMult); //e.g. 397.973175, slideMult: 1.989866

        //基于速度和速度因素计算一个终点
        float slideFactor = 0.1 * slideMult;
        CGPoint finalPoint = CGPointMake(center.x + (velocity.x * slideFactor),
                                        center.y + (velocity.y * slideFactor));
        //限制最小[cornerRadius]和最大边界值[self.view.bounds.size.width - cornerRadius],以免拖动出屏幕界限
        finalPoint.x = MIN(MAX(finalPoint.x, cornerRadius),self.view.bounds.size.width - cornerRadius);
        finalPoint.y = MIN(MAX(finalPoint.y, cornerRadius),self.view.bounds.size.height - cornerRadius);
        //使用 UIView 动画使 view 滑行到终点
       [UIView animateWithDuration:slideFactor*2 delay:0 options:UIViewAnimationOptionCurveEaseOut
       animations:^{
            sender.view.center = finalPoint;
        }
        completion:nil];
    }

}
//旋转
-(void)rotationAction:(UIRotationGestureRecognizer *)sender{
    sender.view.transform = CGAffineTransformRotate(sender.view.transform, sender.rotation);
    sender.rotation = 0.0;
}
//横扫
-(void)swipeAction:(UISwipeGestureRecognizer *)sender{
    switch (sender.direction) {
            //手势向下滑动
        case UISwipeGestureRecognizerDirectionDown:{
            //创建CATransition 对象
            CATransition *animation=[CATransition animation];
            animation.delegate=self;    //动画代理
            animation.duration=1.0f;    //动画持续时间
            animation.timingFunction=UIViewAnimationCurveEaseInOut; //速度控制函数,控制动画运行的节奏
            animation.type=kCATransitionMoveIn; //设置运动type
            animation.subtype=kCATransitionFromBottom;  //视图向下滑动
            [sender.view.layer addAnimation:animation forKey:@"move in"];
        }
            break;
        //向上滑动
        case UISwipeGestureRecognizerDirectionUp:{
            CATransition *animation = [CATransition animation];
            animation.delegate = self;
            animation.duration = 1.0f;
            animation.timingFunction = UIViewAnimationCurveEaseInOut;
            animation.type = kCATransitionMoveIn;
            animation.subtype = kCATransitionFromTop;
            [sender.view.layer addAnimation:animation forKey:@"move in"];
        }
            break;
        //向左
        case UISwipeGestureRecognizerDirectionLeft:{
            CATransition *animation = [CATransition animation];
            animation.delegate = self;
            animation.duration = 1.0f;
            animation.timingFunction = UIViewAnimationCurveEaseInOut;
            animation.type = kCATransitionMoveIn;
            animation.subtype = kCATransitionFromRight;
            [sender.view.layer addAnimation:animation forKey:@"move in"];
        }
            break;
        //向右横扫
        case UISwipeGestureRecognizerDirectionRight:{
            CATransition *animation = [CATransition animation];
            animation.delegate = self;
            animation.duration = 1.0f;
            animation.timingFunction = UIViewAnimationCurveEaseInOut;
            animation.type = kCATransitionMoveIn;
            animation.subtype = kCATransitionFromLeft;
            [sender.view.layer addAnimation:animation forKey:@"move in"];
        }
            break;

        default:
            break;
    }

}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

第二次编辑 2017年 3月 3日

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值