您的位置:首页 > 移动开发 > IOS开发

iOS 手势识别器

2015-08-10 22:16 447 查看
iOS的输入事件

触摸事件

手势识别

一、iOS的输入事件

 

触摸事件(滑动、点击)

一、iOS事件对象都是UIEvent类的实例

UIEvent类对事件类型定义了enum常量:

typedef NS_ENUM(NSInteger, UIEventType){

     UIEventTypeTouches,

     UIEventTypeMotion,

     UIEventRemoteControl,

};

触摸事件必须是继承UIResponser的

二、触摸事件

一、UIView,有4种处理不同的触摸事件

UIView是UIResponder的子类,可以覆盖下列4个方法处理不同的触摸事件。

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

复制代码

#pragma mark - UITouch事件

#pragma mark 触摸开始

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

{

    NSLog(@"触摸开始");

    for (UITouch *touch in touches) {

        NSLog(@"%@", touch);

    }

}

 

#pragma mark 触摸移动

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

{

    NSLog(@"触摸移动Touch对象个数:%d",[touches count]);

    // 要移动界面上黄颜色的视图

    

    // 1. 得到当前手指的位置

    UITouch *touch = [touches anyObject
4000
];

    CGPoint location = [touch locationInView:self.view];

    // 2. 得到上一次手指的位置

    CGPoint preLocation = [touch previousLocationInView:self.view];

    // 3. 计算两个位置之间的偏移

    CGPoint offset = CGPointMake(location.x - preLocation.x, location.y - preLocation.y);

    // 4. 使用计算出来的偏移量,调整视图的位置

    [_demoView setCenter:CGPointMake(_demoView.center.x + offset.x, _demoView.center.y + offset.y)];

    

2⃣️触摸事件的处理

如果hit-test视图无法处理事件,则通过响应者链向上传递

1.如果hit-test视图的控制器存在,就传递给控制器;如果控制器不存在,则将其传递给它的父视图

2.如果视图或它的控制器无法处理收到的事件或消息,则将其传递给该视图的父视图

3.每一个在视图继承树中的上层视图如果不能处理收到的事件或消息,则重复上面的步骤1,2

4.在视图继承树的最上层视图,如果也不能处理收到的事件或消息,则其将事件或消息传递给窗口对象进行处理

5. 如果窗口对象也不能进行处理,则其将事件或消息传递给UIApplication对象

6.如果UIApplication也不能处理该事件或消息,则将其丢弃

当用户点击屏幕时,会产生一个UITouch对象传递给UIApplication,然后由window负责查找最适合相应触摸事件的视图对象(hitTest,pointInside)

找到合适的视图之后,Touch方法由对应的视图完成,上级视图不再接管

3⃣️不接受处理事件的三种方法

不接收用户交互:userInteractionEnabled = NO;

隐藏:hidden = YES;

透明:alpha = 0~0.01

三、手势识别

1⃣️iOS目前支持的手势识别(6种)

UITapGestureRecognizer(点按)

UIPinchGestureRecognizer(捏合)

UIPanGestureRecognizer(拖动)

UISwipeGestureRecognizer(轻扫)

UIRotationGestureRecognizer(旋转)

UILongPressGestureRecognizer(长按)

2⃣️手势识别的使用方法(4步)

通常在视图加载的时候定义(UIGestureRecognizer是抽象类,需要实例化使用)

创建手势识别实例

设置手势识别属性,例如手指数量,方向等

将手势识别附加到指定的视图之上

编写手势触发响应方法

3⃣️手势识别的状态(7个)

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

    UIGestureRecognizerStatePossible,

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

    UIGestureRecognizerStateBegan,

    // 手势状态改变

    UIGestureRecognizerStateChanged,

    // 手势完成

    UIGestureRecognizerStateEnded,

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

    UIGestureRecognizerStateCancelled, 

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

    UIGestureRecognizerStateFailed,

    // 识别到手势识别

    UIGestureRecognizerStateRecognized =UIGestureRecognizerStateEnded 

  2.手势识别的属性

state——手势状态

view——手势发生视图

常用方法

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

复制代码

- (void)viewDidLoad

{

    [super viewDidLoad];

   

    // 根据实例化方法,我们知道:

    // 1.有一个处理消息的对象,应该是self

    // 2.我们需要定义一个方法,当手势识别检测到的时候,运行

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapAction:)];

    // setNumberOfTapsRequired 点按次数

    [tap setNumberOfTapsRequired:1];

    // setNumberOfTouchesRequired 点按的手指数量

    [tap setNumberOfTouchesRequired:1];

    // 把手势识别增加到视图上

    [self.demoView addGestureRecognizer:tap];

    

   

    UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinchAction:)];

    [self.demoView addGestureRecognizer:pinch];

    

   

    UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(rotationAction:)];

    [self.demoView addGestureRecognizer:rotation];

    

   

    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panAction:)];

    [self.demoView addGestureRecognizer:pan];

    

   

    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressAction:)];

    [self.demoView addGestureRecognizer:longPress];

    

   

    // 向左扫

    UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeAction:)];

    [swipeLeft setDirection:UISwipeGestureRecognizerDirectionLeft];

    [self.view addGestureRecognizer:swipeLeft];

    // 向右扫

    UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeAction:)];

    [swipeRight setDirection:UISwipeGestureRecognizerDirectionRight];

    [self.view addGestureRecognizer:swipeRight];

    // 向上扫

    UISwipeGestureRecognizer *swipeTop = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeAction:)];

    [swipeTop setDirection:UISwipeGestureRecognizerDirectionUp];

    [self.view addGestureRecognizer:swipeTop];

    // 向下扫

    UISwipeGestureRecognizer *swipeDown = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeAction:)];

    [swipeDown setDirection:UISwipeGestureRecognizerDirectionDown];

    [self.view addGestureRecognizer:swipeDown];

}

 

- (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

 

#pragma mark - 轻扫手势

- (void)swipeAction:(UISwipeGestureRecognizer *)sender

{

    NSLog(@"%d", sender.direction);

    switch (sender.direction) {

        case UISwipeGestureRecognizerDirectionLeft:

            NSLog(@"向左扫");

            break;

        case UISwipeGestureRecognizerDirectionRight:

            NSLog(@"向右扫");

            break;

        case UISwipeGestureRecognizerDirectionUp:

            NSLog(@"向上扫");

            break;

        case UISwipeGestureRecognizerDirectionDown:

            NSLog(@"向下扫");

            break;

        default:

            break;

    }

}

 

#pragma mark - 长按手势

- (void)longPressAction:(UILongPressGestureRecognizer *)sender

{

    // 我们可以利用demoView的Tag属性,默认时tag=0

    // 如果tag=0,我们放大一倍,否则,我们缩小一半

    CGFloat scale;

    if (_demoView.tag == 0) {

        scale = 2.0;

        _demoView.tag = 1;

    } else {

        scale = 0.5;

        _demoView.tag = 0;

    }

    

    sender.view.transform = CGAffineTransformScale(sender.view.transform, scale, scale);

}

 

#pragma mark - 拖放手势

- (void)panAction:(UIPanGestureRecognizer *)sender

{

    // 在拖放手势中是需要考虑手指的状态的UIGestureRecognizerState

    // 在拖放手势中使用的状态是UIGestureRecognizerStateChanged

    // 通常在使用拖放手势的时候,当手指离开的时候,应该做一个很小的动作,提醒用户拖放完成

    if (sender.state == UIGestureRecognizerStateChanged) {

        // locationInView

        [_demoView setCenter:[sender locationInView:self.view]];

    } else if (sender.state == UIGestureRecognizerStateEnded) {

        [_demoView setBackgroundColor:[UIColor yellowColor]];

    }

}

 

#pragma mark - 旋转手势

- (void)rotationAction:(UIRotationGestureRecognizer *)sender

{

    sender.view.transform = CGAffineTransformRotate(sender.view.transform, sender.rotation);

    

    // 和捏合操作类似,旋转角度同样需要方福伟

    sender.rotation = 0.0f;

}

 

#pragma mark - 捏合手势

- (void)pinchAction:(UIPinchGestureRecognizer *)sender

{

    // 有关转换的内容,我们在后续动画部分再继续

    sender.view.transform = CGAffineTransformScale(sender.view.transform, sender.scale, sender.scale);

    

    // 缩放功能很简单,但是不要忘记将比例复位

    sender.scale = 1.0f;

    NSLog(@"捏我了");

}

 

#pragma mark - 点按手势

- (void)tapAction:(UITapGestureRecognizer *)sender

{

   

    NSLog(@"点我了 %@", sender);

}

 

#pragma mark - 手势触摸事件

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

{

    NSLog(@"触摸事件!");

    // 1. 先取出UITouch对象

    // 2. 判断响应点击的UIView是不是我们需要的

    UITouch *touch = [touches anyObject];

    if ([touch view] == _imageView) {

        NSLog(@"点到图像了!");

    }

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ios 手势识别