iOS 手勢UIGestureRecognizer

來源:互聯網
上載者:User

標籤:手勢識別   ios開發   



 在 iPhone 或 iPad 的開發中,除了用 touchesBegan / touchesMoved / touchesEnded 這組方法來控制使用者的手指觸控外,也可以用 UIGestureRecognizer 的衍生類別來進行判斷。用 UIGestureRecognizer 的好處在於有現成的手勢,開發人員不用自己計算手指移動軌跡。UIGestureRecognizer的衍生類別有以下幾種:


UITapGestureRecognizer
UIPinchGestureRecognizer
UIRotationGestureRecognizer
UISwipeGestureRecognizer
UIPanGestureRecognizer
UILongPressGestureRecognizer


從命名上不難瞭解這些類別所對應代表的手勢,分別是 Tap(點一下)、Pinch(二指往內或往撥出動)、Rotation(旋轉)、Swipe(滑動,快速移動)、Pan (拖移,慢速移動)以及 LongPress(長按)。這些手勢別在使用上也很簡單,只要在使用前定義並添加到對應的視圖上即可。


複製代碼
// 定義一個 recognizer, 並加到需要偵測該手勢的 UIView 元件上
- (void)viewDidLoad {
UISwipeGestureRecognizer* recognizer;
// handleSwipeFrom 是偵測到手勢,所要呼叫的方法
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:selfaction:@selector(handleSwipeFrom)];
// 不同的 Recognizer 有不同的實體變數
// 例如 SwipeGesture 可以指定方向
// 而 TapGesture 則可以指定次數
recognizer.direction = UISwipeGestureRecognizerDirectionUp
[self.view addGestureRecognizer:recognizer];
[recognizer release];
}


- (void)handleSwipeFrom:(UISwipeGestureRecognizer*)recognizer {
// 觸發手勢事件後,在這裡作些事情


// 底下是刪除手勢的方法
[self.view removeGestureRecognizer:recognizer];
}
複製代碼
問題來了。有些手勢其實是互相關聯的,例如 Tap 與 LongPress、Swipe與 Pan,或是 Tap 一次與Tap 兩次。當一個 UIView 同時添加兩個相關聯的手勢時,到底我這一下手指頭按的要算是 Tap 還是 LongPress?如果照預設作法來看,只要「先滿足條件」的就會跳出並呼叫對應方法,舉例來說,如果同時註冊了 Pan 和 Swipe,只要手指頭一移動就會觸發 Pan 然後跳出,因而永遠都不會發生 Swipe;單點與雙點的情形也是一樣,永遠都只會觸發單點,不會有雙點。


那麼這個問題有解嗎?答案是肯定的,UIGestureRecognizer 有個方法叫做requireGestureRecognizerToFail,他可以指定某一個 recognizer,即便自己已經滿足條件了,也不會立刻觸發,會等到該指定的 recognizer 確定失敗之後才觸發。以同時支援單點與雙點的手勢為例,代碼如下:


複製代碼
- (void)viewDidLoad {
// 單擊的 Recognizer
UITapGestureRecognizer* singleRecognizer;
singleRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:selfaction:@selector(handleSingleTapFrom)];
singleTapRecognizer.numberOfTapsRequired = 1; // 單擊
[self.view addGestureRecognizer:singleRecognizer];


// 雙擊的 Recognizer
UITapGestureRecognizer* double;
doubleRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:selfaction:@selector(handleDoubleTapFrom)];
doubleTapRecognizer.numberOfTapsRequired = 2; // 雙擊
[self.view addGestureRecognizer:doubleRecognizer];


// 關鍵在這一行,如果雙擊確定偵測失敗才會觸發單擊
[singleRecognizer requireGestureRecognizerToFail:doubleRecognizer];
[singleRecognizer release];
[doubleRecognizer release];

Demo
首先建立一個基於Sigle view Application的項目,名為GestureTest;我的項目結構如下:






往viewController.xib檔案裡拖動一個imageView,並使覆蓋整個螢幕,改動屬性為:






viewController.h檔案:


 


 


1.     #import <UIKit/UIKit.h>  


2.       


3.     @interface ViewController : UIViewController{  


4.         IBOutlet UIImageView *imageView;  


5.     }  


6.     @property (nonatomic,retain)IBOutlet UIImageView *imageView;  


7.     @end  


並使xib檔案裡的imageView與之串連;


 


然後是viewController.m檔案的實現部分:


 


 


1.     @synthesize imageView;  


2.       


3.     CGFloat lastScaleFactor=1;//放大、縮小  


4.     CGFloat  netRotation;//旋轉  


5.     CGPoint netTranslation;//平衡  


6.     NSArray *images;//圖片數組  


7.     int imageIndex=0;//數組下標  


8.       


9.     - (void)viewDidLoad  


10.   {  


11.       //1、建立手勢執行個體,並串連方法handleTapGesture,點選手勢  


12.       UITapGestureRecognizer *tapGesture=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTapGesture:)];  


13.       //設定手勢點擊數,雙擊:點2下  


14.       tapGesture.numberOfTapsRequired=2;  


15.       // imageView添加手勢識別  


16.       [imageView addGestureRecognizer:tapGesture];  


17.       //釋放記憶體  


18.       [tapGesture release];  


19.         


20.       //2、手勢為捏的姿勢:按住option按鈕配合滑鼠來做這個動作在虛擬器上  


21.       UIPinchGestureRecognizer *pinchGesture=[[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(handlePinchGesture:)];  


22.       [imageView addGestureRecognizer:pinchGesture];//imageView添加手勢識別  


23.       [pinchGesture release];  


24.         


25.       //3、旋轉手勢:按住option按鈕配合滑鼠來做這個動作在虛擬器上  


26.       UIRotationGestureRecognizer *rotateGesture=[[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(handleRotateGesture:)];  


27.       [imageView addGestureRecognizer:rotateGesture];  


28.       [rotateGesture release];  


29.         


30.       //4、拖手勢  


31.       UIPanGestureRecognizer *panGesture=[[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePanGesture:)];  


32.      // [imageView addGestureRecognizer:panGesture];  


33.       [panGesture release];  


34.         


35.       //5、划動手勢  


36.       images=[[NSArray alloc]initWithObjects:@"cell.jpg",@"heihua.jpg",@"xuanyi.jpg", nil];  


37.       //右劃  


38.       UISwipeGestureRecognizer *swipeGesture=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipeGesture:)];  


39.       [imageView addGestureRecognizer:swipeGesture];  


40.       [swipeGesture release];  


41.       //左劃  


42.       UISwipeGestureRecognizer *swipeLeftGesture=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipeGesture:)];  


43.       swipeGesture.direction=UISwipeGestureRecognizerDirectionLeft;//不設定黑夜是右  


44.       [imageView addGestureRecognizer:swipeLeftGesture];  


45.       [swipeLeftGesture release];  


46.         


47.       //6、長按手勢  


48.       UILongPressGestureRecognizer *longpressGesutre=[[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(handleLongpressGesture:)];  


49.       //長按時間為1秒  


50.       longpressGesutre.minimumPressDuration=1;  


51.       //允許15秒中運動  


52.       longpressGesutre.allowableMovement=15;  


53.       //所需觸摸1次  


54.       longpressGesutre.numberOfTouchesRequired=1;  


55.       [imageView addGestureRecognizer:longpressGesutre];  


56.       [longpressGesutre release];  


57.         


58.       [super viewDidLoad];  


59.       // Do any additional setup after loading the view, typically from a nib.  


60.   }  


61.   //雙擊螢幕時會調用此方法,放大和縮小圖片  


62.   -(IBAction)handleTapGesture:(UIGestureRecognizer*)sender{  


63.       //判斷imageView的內容模式是否是UIViewContentModeScaleAspectFit,該模式是原比例,按照圖片原時比例顯示大小  


64.       if(sender.view.contentMode==UIViewContentModeScaleAspectFit){  


65.           //把imageView模式改成UIViewContentModeCenter,按照圖片原先的大小顯示中心的一部分在imageView  


66.           sender.view.contentMode=UIViewContentModeCenter;  


67.       }else{  


68.           sender.view.contentMode=UIViewContentModeScaleAspectFit;  


69.       }  


70.   }  


71.   //捏的手勢,使圖片放大和縮小,捏的動作是一個連續的動作  


72.   -(IBAction)handlePinchGesture:(UIGestureRecognizer*)sender{  


73.       //得到sender捏手勢的大小  


74.       CGFloat factor=[(UIPinchGestureRecognizer*)sender scale];  


75.       if(factor>1){  


76.           //圖片放大  


77.           sender.view.transform=CGAffineTransformMakeScale(lastScaleFactor+(factor-1), (lastScaleFactor+(factor-1)));  


78.                                                              


79.       }else{  


80.           //縮小  


81.           sender.view.transform=CGAffineTransformMakeScale(lastScaleFactor*factor, lastScaleFactor*factor);  


82.                                                              


83.       }  


84.       //狀態是否結束,如果結束儲存資料  


85.       if(sender.state==UIGestureRecognizerStateEnded){  


86.           if(factor>1){  


87.               lastScaleFactor+=(factor-1);  


88.           }else{  


89.               lastScaleFactor*=factor;  


90.           }  


91.       }  


92.   }  


93.   //旋轉手勢  


94.   -(IBAction)handleRotateGesture:(UIGestureRecognizer*)sender{  


95.       //浮點類型,得到sender的旋轉度數  


96.       CGFloat rotation=[(UIRotationGestureRecognizer*)sender rotation];  


97.       //旋轉角度CGAffineTransformMakeRotation  


98.       CGAffineTransform transform=CGAffineTransformMakeRotation(rotation+netRotation);  


99.       //改變映像角度  


100.      sender.view.transform=transform;  


101.      //狀態結束,儲存資料  


102.      if(sender.state==UIGestureRecognizerStateEnded){  


103.          netRotation+=rotation;  


104.      }  


105.         


106.  }  


107.  //拖手勢  


108.  -(IBAction)handlePanGesture:(UIGestureRecognizer*)sender{  


109.      //得到拖的過程中的xy座標  


110.      CGPoint translation=[(UIPanGestureRecognizer*)sender translationInView:imageView];  


111.      //平移圖片CGAffineTransformMakeTranslation  


112.      sender.view.transform=CGAffineTransformMakeTranslation(netTranslation.x+translation.x, netTranslation.y+translation.y);  


113.      //狀態結束,儲存資料  


114.      if(sender.state==UIGestureRecognizerStateEnded){  


115.          netTranslation.x+=translation.x;  


116.          netTranslation.y+=translation.y;  


117.      }  


118.        


119.  }  


120.  //划動手勢  


121.  -(IBAction)handleSwipeGesture:(UIGestureRecognizer*)sender{  


122.      //划動的方向  


123.      UISwipeGestureRecognizerDirection direction=[(UISwipeGestureRecognizer*) sender direction];  


124.      //判斷是上下左右  


125.      switch (direction) {  


126.          case UISwipeGestureRecognizerDirectionUp:  


127.              NSLog(@"up");  


128.              break;  


129.          case UISwipeGestureRecognizerDirectionDown:  


130.              NSLog(@"down");  


131.              break;  


132.          case UISwipeGestureRecognizerDirectionLeft:  


133.              NSLog(@"left");  


134.              imageIndex++;//下標++  


135.              break;  


136.          case UISwipeGestureRecognizerDirectionRight:  


137.              NSLog(@"right");  


138.              imageIndex--;//下標--  


139.              break;  


140.          default:  


141.              break;  


142.      }  


143.      //得到不越界不<0的下標  


144.      imageIndex=(imageIndex<0)?([images count]-1):imageIndex%[images count];  


145.      //imageView顯示圖片  


146.      imageView.image=[UIImage imageNamed:[images objectAtIndex:imageIndex]];  


147.        


148.  }  


149.  //長按手勢  


150.  -(IBAction)handleLongpressGesture:(UIGestureRecognizer*)sender{  


151.      //建立警告  


152.      UIActionSheet *actionSheet=[[UIActionSheet alloc]initWithTitle:@"Image options" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:@"Save Image",@"Copy", nil];  


153.      //當前view顯示警告  


154.      [actionSheet showInView:self.view];  


155.      [actionSheet release];  


156.  }  


157.  -(void)dealloc{  


158.      [images release];  


159.      [imageView release];  


160.      [super dealloc];  


161.  }  

iOS 手勢UIGestureRecognizer

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.