手勢識別

監聽觸摸事件的做法

  • 如果想監聽一個view上面的觸摸事件,之前的做法是
    1.自定義一個view
    2.實現view的touches方法,在方法內部實現具體處理代碼
  • 注意:通過touches方法監聽view觸摸事件,有很明顯的幾個缺點
    1.必須得自定義view
    2.由于是在view內部的touches方法中監聽觸摸事件,因此默認情況下,無法讓其他外界對象監聽view的觸摸事件
    3.不容易區分用戶的具體手勢行為
  • iOS 3.2之后,蘋果推出了手勢識別功能(Gesture Recognizer),在觸摸事件處理方面,大大簡化了開發者的開發難度

UIGestureRecognizer的使用

 1.什么是UIGestureRecognizer:
       UIGestureRecognizer手勢識別器
  2.優點 :
       利用UIGestureRecognizer,能輕松識別用戶在某個view上面做的一些常見手勢
  3.注意點:
      UIGestureRecognizer是一個抽象類,定義了所有手勢的基本行為,使用它的子類才能處理具體的手勢
  4.UIGestureRecognizer的子類
        UITapGestureRecognizer(敲擊)
        UIPinchGestureRecognizer(捏合,用于縮放)
        UIPanGestureRecognizer(拖拽)
        UISwipeGestureRecognizer(輕掃)
        UIRotationGestureRecognizer(旋轉)
        UILongPressGestureRecognizer(長按)

手勢的使用

注意:在使用手勢時,涉及到形變的手勢,不能使用make的transform方法
//self.imageV.transform = CGAffineTransformMakeTranslation(point.x, point.y);
因為當移動完畢后,在次點擊拖動時,圖片會回到最開始的位置,make的transform方法是相對于最原始的位置進行形變的而且只會執行一次,所以在拖動的時候,總是會回到起始點后,所以在拖動過程中,就會出現震顫的效果;
可以使用沒有make的transform方法
self.imageV.transform = CGAffineTransformTranslate(self.imageV.transform, point.x, point.y);
因為這個方法的形變值,是相對上一次而非最初的狀態的形變值,因此獲取相對最初位置的偏移量是累加了之前的偏移量的值,獲取到的偏移值會比實際的偏移值大很多,但是需要的偏移量是要相對圖片最初位置的偏移量,所以,在這里需要調用setTranslation: inView:方法,在拖動時,將上一次的偏移值清空,以獲取拖動時相對初始位置的偏移值.

  • 1.UITapGestureRecognizer(敲擊)
    /*************手勢點按*************/
-(void)tapTestGes{
    //創建手勢
    UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGes)];//當圖片沒有接受到手勢的觸摸事件后,不會調用tap方法
    //給圖片添加手勢
    [self.imageV addGestureRecognizer:tap];
}
//手勢的方法
-(void)tapGes{
    NSLog(@"%s",__func__);
}
  • 2.UIPinchGestureRecognizer(捏合,用于縮放)
    /*************捏合手勢*************/
-(void)pinchGes{
    UIPinchGestureRecognizer * pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchGes:)];
    pinch.delegate = self;
    [self.imageV addGestureRecognizer:pinch];
}
//捏合手勢的方法
-(void)pinchGes:(UIPinchGestureRecognizer *)pinch
{
    self.imageV.transform = CGAffineTransformScale(self.imageV.transform, pinch.scale, pinch.scale);//如果縮放倍數寫成常數,那么久只能放大或縮小
    [pinch setScale:1];
}
  • 3.UIPanGestureRecognizer(拖拽)
    /*************拖動手勢*************/
-(void)panGes{
    UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGes:)];
    [self.imageV addGestureRecognizer:pan];
}
//平移圖片
-(void)panGes:(UIPanGestureRecognizer *)pan
{
    //獲取圖片相對最開始時的自己的位置
    CGPoint point = [pan translationInView:self.imageV];
    self.imageV.transform = CGAffineTransformTranslate(self.imageV.transform, point.x, point.y);
    //重置圖片的移動距離(相對于上一次)
        NSLog(@"%@",NSStringFromCGPoint(point));
    [pan setTranslation:CGPointZero inView:self.imageV];
}
  • 4.UISwipeGestureRecognizer(輕掃)
    //設置輕掃方向
    1.只有在同一水平方向上的手勢可以拼接,不在同一水平方向上的手勢不可以拼接
    2.拼接以后只能識別圖片被輕掃了,但不能識別往哪個方向輕掃
    3.要想識別圖片是往哪個方向輕掃了,需要添加兩個輕掃手勢對象,其中一個手勢對象必須指明要滑動的方向
    /*************輕掃手勢*************/
-(void)swipeGes{
    //創建輕掃手勢
    UISwipeGestureRecognizer * swipe1 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGes:)];
    //設置輕掃方向
    swipe1.direction =  UISwipeGestureRecognizerDirectionLeft;
    //給圖片添加輕掃手勢
    [self.imageV addGestureRecognizer:swipe1];
    //創建第二個輕掃手勢
    UISwipeGestureRecognizer * swipe2 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGes:)];
    //給圖片添加第二個輕掃手勢
    [self.imageV addGestureRecognizer:swipe2];
}
//輕掃手勢方法的實現
-(void)swipeGes:(UISwipeGestureRecognizer *)swipe
{
    if (swipe.direction == UISwipeGestureRecognizerDirectionLeft) {
        NSLog(@"向左輕掃圖片");
    }else if (swipe.direction == UISwipeGestureRecognizerDirectionRight){
        NSLog(@"向右輕掃圖片");
    }else{
    NSLog(@"無法識別輕掃圖片的方向");
    }
}
  • 5.UIRotationGestureRecognizer(旋轉)
    /*************旋轉手勢*************/
-(void)rotationGes{
    UIRotationGestureRecognizer * rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotationGes:)];
    rotation.delegate = self;
    [self.imageV addGestureRecognizer:rotation];
}
//旋轉手勢的方法
-(void)rotationGes:(UIRotationGestureRecognizer *)rotation
{
    self.imageV.transform = CGAffineTransformRotate(self.imageV.transform, rotation.rotation);
    [rotation setRotation:0];
}
  • 6.UILongPressGestureRecognizer(長按)
    /*************手勢長按*************/
-(void)longPressGes
{
    //創建長按手勢
    UILongPressGestureRecognizer * longP = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPGes:)];
    //給圖片添加長按手勢
    [self.imageV addGestureRecognizer:longP];
}
//當長按的時候會調用此方法
-(void)longPGes:(UILongPressGestureRecognizer *)longP
{
    //判斷長按手勢的狀態.因此,方法應該傳入長按手勢對象
    if (longP.state == UIGestureRecognizerStateBegan) {
        NSLog(@"開始長按");
    }else if (longP.state == UIGestureRecognizerStateChanged){
        NSLog(@"開始滑動");
    }else if (longP.state == UIGestureRecognizerStateEnded){
        NSLog(@"結束長按");
    }
}
  • 設置是否允許手指觸摸,需要設置代理,并實現下面的代理方法
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    //獲取當前觸摸點的位置
    CGPoint curP = [touch locationInView:self.imageV];
    //設置可觸摸的范圍(左側不可觸摸,右側可以觸摸)
    if (curP.x <= self.imageV.frame.size.width * 0.5) {
        NSLog(@"%@",NSStringFromCGPoint(curP));
        NSLog(@"不可以觸摸");
        return NO;
    }else{
        NSLog(@"%@",NSStringFromCGPoint(curP));
        NSLog(@"可以觸摸");
        return YES;
    }
  • 設置是否允許接受多個手勢,設置對應手勢的代理,并實現下面的dialing方法
//實現代理方法
//同時執行多個手勢操作
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容