iOS手势识别

本文详细介绍了iOS中手势识别的概念、手势识别器(GestureRecognizer)的使用方法及状态变化,包括如何创建、配置手势识别器以及如何实现多手势识别。通过实例演示了长按、旋转、缩放、轻扫和拖拽等手势的实现,以及如何解决手势冲突问题,提供了iOS应用开发中手势交互设计的实用指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

一、手势识别与触摸事件

 

1、如果想监听一个view上面的触摸事件,可选的做法是:

(1)自定义一个view

(2)实现view的touches方法,在方法内部实现具体处理代码

 

2、通过touches方法监听view触摸事件,有很明显的几个缺点

 

(1)必须得自定义view

(2)由于是在view内部的touches方法中监听触摸事件,因此默认情况下,无法让其他外界对象监听view的触摸事件

(3)不容易区分用户的具体手势行为

 

3、iOS 3.2之后,苹果推出了手势识别功能(Gesture Recognizer),在触摸事件处理方面,大大简化了开发者的开发难度

 

 

二、手势识别——Gesture Recognizer

 

1、手势识别器:UIGestureRecognizer

 

(1)UIGestureRecognizer是一个抽象类,定义了所有手势的基本行为,使用它的子类才能处理具体的手势

(2)子类的继承和功能

图示:

 

 

2、手势识别的使用方法及步骤

 

(1)创建手势识别实例

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

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

(4)编写手势触发监听方法

(5)手势触发监听方法后,要还原手势识别实例的属性,比如:获取了缩放比例,然后给某个控件进行了缩放,最后再把缩放比例还原为1。这样后续的手势操作会从新开始,避免错误

 

3、手势识别的状态

 

(1)类似于触摸事件,手势识别实例包含了属性 state,可以区别此时手势的状态

(2)state属性为枚举类型:

 

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

    UIGestureRecognizerStatePossible,

 

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

    UIGestureRecognizerStateBegan, (类似于 touchesBegan)

 

    <3> 手势状态改变

    UIGestureRecognizerStateChanged, (类似于 touchesMoved)

 

    <4> 手势完成

    UIGestureRecognizerStateEnded, (类似于 touchesEnded)

 

    <5> 手势取消,恢复至Possible状态

    UIGestureRecognizerStateCancelled, (比如手指按下按钮,然后从其他地方抬起)

 

    <6> 手势失败,恢复至Possible状态

    UIGestureRecognizerStateFailed,

 

    <7> 识别到手势结束

    UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded

 

4、不同手势识别子类具有不同的属性或方法,几个重要的举例如下:

 

(1)在“轻点”手势中: 

 

  <1> 需要连续敲击2次触发手势

  tap.numberOfTapsRequired = 2;

 

  <2> 需要2根手指一起敲击

  tap.numberOfTouchesRequired = 2;

 

(2)在“旋转”手势中:

 

  <1>获取用户旋转角度 

  CGFloat rotation;

   

  <2>获取用户旋转速度

   CGFloat velocity

 

(3)在“轻扫”手势中:

   <1>扫动的方向,注意,一个轻扫手势识别对象,只能对应一个扫动方向

   UISwipeGestureRecognizerDirection

 

(4)在“拖拽”手势中:

   <1> 获取移动的距离 ,这个是对象方法

   - (CGPoint)translationInView:(nullable UIView *)view; 

 

  <2>清除手势移动的距离(为了下次手势事件的正确计算)

    例: [pan setTranslation:CGPointZero inView:self.view];

 

 

5、实现多手势识别(比如缩放的同时可以旋转)

 

(1)设置手势识别器的代理

  

(2)实现相应的代理方法,支持多手势识别。

 

 

三、demo实例

 

1、图示

 

 

2、贴出部分代码

 

#pragma mark - 长按手势
- (IBAction)longPressBtnClick:(id)sender {
    
    //长按手势识别器,正常下会执行两次方法,不晓得为啥     
    UILongPressGestureRecognizer * longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longClick:)];
    
    [self.view addGestureRecognizer:longPress];
    //代理
    longPress.delegate = self;
    
}

-(void)longClick:(UILongPressGestureRecognizer *)longPress
{

    //根据状态判断
    if(longPress.state==UIGestureRecognizerStateBegan)
    {
        NSLog(@"开始长按了~~");

    }
    
}

#pragma mark - 旋转手势
- (IBAction)rotateBtnClick {
 
    UIRotationGestureRecognizer * rotate = [[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(rotateClick:)];
    
    [self.view addGestureRecognizer:rotate];
    
    //增加代理
     rotate.delegate =self;
      
}

-(void)rotateClick:(UIRotationGestureRecognizer *)rotate
{

    CGFloat ratation = rotate.rotation;
    self.headerView.transform = CGAffineTransformRotate(self.headerView.transform, ratation);

    //清除掉累加的 rotation
    rotate.rotation=0;
}




#pragma mark - 缩放手势
- (IBAction)pinchBtnClick {
    
    UIPinchGestureRecognizer * pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinchClick:)];
    
    [self.view addGestureRecognizer:pinch];
    
    //增加代理
    pinch.delegate = self;
    
}


-(void)pinchClick:(UIPinchGestureRecognizer *)pinch
{
    CGFloat scale = pinch.scale;
    self.headerView.transform = CGAffineTransformScale(self.headerView.transform, scale, scale);
    
    //同样清除
    pinch.scale = 1;

}




#pragma mark - 轻扫手势
- (IBAction)swipeBtnClick {

    UISwipeGestureRecognizer * swipe = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeClick:)];
    
    //向右扫动手势
    swipe.direction= UISwipeGestureRecognizerDirectionRight;
    [self.view addGestureRecognizer:swipe];
    
    UISwipeGestureRecognizer * swipe2 =[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeClick:)];
    
    //向左扫动手势
    swipe2.direction= UISwipeGestureRecognizerDirectionLeft;
    [self.view addGestureRecognizer:swipe2];
}

-(void)swipeClick:(UISwipeGestureRecognizer *)swipe
{

    if (swipe.direction==UISwipeGestureRecognizerDirectionRight) {    
        [UIView animateWithDuration:0.3 animations:^{
       
        self.headerView.transform = CGAffineTransformTranslate(self.headerView.transform, 100, 0);
            
            
        }completion:^(BOOL finished) {
            
            [UIView animateWithDuration:0.5 animations:^{
                self.headerView.transform = CGAffineTransformIdentity;
                
            }];
            
            
        }];
     
    }
    else if (swipe.direction==UISwipeGestureRecognizerDirectionLeft) {
    
        [UIView animateWithDuration:0.3 animations:^{
            
                self.headerView.transform = CGAffineTransformTranslate(self.headerView.transform, -100, 0);          
            
        }completion:^(BOOL finished) {
            
            [UIView animateWithDuration:0.5 animations:^{
                self.headerView.transform = CGAffineTransformIdentity;

            }];
        }];
    }
}




#pragma mark - 拖拽手势
- (IBAction)panBtnClick {
  
    UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panClick:)];
    
    [self.view addGestureRecognizer:pan];
     
}


-(void)panClick:(UIPanGestureRecognizer *)pan
{
    CGPoint point = [pan translationInView:self.view];
    
    self.headerView.transform = CGAffineTransformTranslate(self.headerView.transform, point.x, point.y);

    [pan setTranslation:CGPointZero inView:self.view];
}


//手势识别代理实现
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;

}

 

四、补充

1、同一个控件添加多个手势,触发冲突的问题,比如双击和单击。

(1)问题描述

  手势是可以互相关联的,例如 Tap 与 LongPress、Swipe与 Pan,或是 Tap 一次与Tap 两次。当一个 UIView 同时添加两个相关联的手势时,到底我这一下手指头按的要算是 Tap 还是 LongPress?如果照预设作法来看,只要「先满足条件」的就会跳出并呼叫对应方法,举例来说,如果同时注册了 Pan 和 Swipe,只要手指头一移动就会触发 Pan 然后跳出,因而永远都不会发生 Swipe;单点与双点的情形也是一样,永远都只会触发单点,不会有双点。

(2)解决方法:requireGestureRecognizerToFail --手势的对象方法

  指定某一个 recognizer,即便自己已经满足条件了,也不会立刻触发,会等到该指定的 recognizer 确定失败之后才触发。

(3)举例  

  //如果双击确定侦测失败才会触发单击

  [singleRecognizer requireGestureRecognizerToFail:doubleRecognizer];

 

转载于:https://www.cnblogs.com/cleven/p/5374644.html

内容概要:论文提出了一种基于空间调制的能量高效分子通信方案(SM-MC),将传输符号分为空间符号和浓度符号。空间符号通过激活单个发射纳米机器人的索引来传输信息,浓度符号则采用传统的浓度移位键控(CSK)调制。相比现有的MIMO分子通信方案,SM-MC避免了链路间干扰,降低了检测复杂度并提高了性能。论文分析了SM-MC及其特例SSK-MC的符号错误率(SER),并通过仿真验证了其性能优于传统的MIMO-MC和SISO-MC方案。此外,论文还探讨了分子通信领域的挑战、优势及相关研究工作,强调了空间维度作为新的信息自由度的重要性,并提出了未来的研究方向和技术挑战。 适合人群:具备一定通信理论基础,特别是对纳米通信和分子通信感兴趣的科研人员、研究生和工程师。 使用场景及目标:①理解分子通信中空间调制的工作原理及其优势;②掌握SM-MC系统的具体实现细节,包括发射、接收、检测算法及性能分析;③对比不同分子通信方案(如MIMO-MC、SISO-MC、SSK-MC)的性能差异;④探索分子通信在纳米网络中的应用前景。 其他说明:论文不仅提供了详细的理论分析和仿真验证,还给出了具体的代码实现,帮助读者更好地理解和复现实验结果。此外,论文还讨论了分子通信领域的标准化进展,以及未来可能的研究方向,如混合调制方案、自适应调制技术和纳米机器协作协议等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值