IOS 手勢

IOS 手勢

簡介:

1.常見手勢

手勢說明:

  1. Tap(點一下)
  1. Pinch(二指往內或往外撥動,平時經常用到的縮放)
  2. Rotation(旋轉)
  3. Swipe(滑動,快速移動)
  4. Pan (拖移,慢速移動)
  5. LongPress(長按)

使用手勢的步驟

使用手勢很簡單,分為兩步:

  1. 創建手勢實例。當創建手勢時,指定一個回調方法,當手勢開始,改變、或結束時,回調方法被調用。
  2. 添加到需要識別的View中。每個手勢只對應一個View,當屏幕觸摸在View的邊界內時,如果手勢和預定的一樣,那就會回調方法。

ps:一個手勢只能對應一個View,但是一個View可以有多個手勢。

UIImageView *snakeImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"snake.png"]]; 
snakeImageView.frame = CGRectMake(50, 50, 100, 160); 
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] 
initWithTarget:self 
action:@selector(handlePan:)]; 
[snakeImageView addGestureRecognizer:panGestureRecognizer]; 
  1. Tap(點一下)
  1. Pinch(二指往內或往外撥動,平時經常用到的縮放)
  2. Rotation(旋轉)

這三種手勢不用細講比較簡單看下demo即可

講下以下幾點:

  1. Pan拖動手勢速度與拖動結束狀態
  2. 同時觸發兩個view的手勢
  3. 解決手勢依耐性 也叫手勢沖突
  4. 自定義手勢

1.Pan拖動手勢速度與拖動結束狀態

狀態

recognizer.state == UIGestureRecognizerStateEnded


>速度
>~~~
CGPoint velocity = [recognizer velocityInView:self.view]; 

2.同時觸發兩個view的手勢

手勢之間是互斥的,如果你想同時觸發View1和View2的手勢,比如說(1)view1 拖動 View2 拖動 或者 (2)view1 拖動 View 縮放 正常情況只有一個手勢會響應。那么需要實現協議
UIGestureRecognizerDelegate。

1.添加代理

//<UIGestureRecognizerDelegate>

@interface ViewController : UIViewController<UIGestureRecognizerDelegate> 
   
@end 
    
    
  panGestureRecognizer.delegate = self;
  pinchGestureRecognizer.delegate = self;
  rotateRecognizer.delegate = self;

2.實現代理
添加代理的手勢將會進入這個方法

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 
{ 
   return YES; 
} 

Simultaneously//同時的

3.解決手勢依耐性 也叫手勢沖突

比較典型的例子:
pan 拖動手勢和 tap 點擊手勢

pan拖動手勢 通常會觸發tap 手勢,使得pan 和tap 手勢事件同時發生,而使用時往往我們只希望響應生效的手勢,可以用函數 requireGestureRecognizerToFail 來解決手勢沖突問題

[tapRecognizer requireGestureRecognizerToFail:panGestureRecognizer];

意思就是,當如果pan手勢失敗,就是沒發生拖動,才會出發tap手勢。這樣如果你有輕微的拖動,那就是pan手勢發生了。tap的聲音就不會發出來了

4.自定義手勢

自定義手勢繼承:UIGestureRecognizer,實現下面的方法:

– touchesBegan:withEvent: 
– touchesMoved:withEvent: 
– touchesEnded:withEvent: 
- touchesCancelled:withEvent: 

例子:

.h文件
#import <UIKit/UIKit.h> 
typedef enum { 
DirectionUnknown = 0, 
DirectionLeft, 
DirectionRight 
} Direction; 

@interface HappyGestureRecognizer : UIGestureRecognizer 
@property (assign) int tickleCount; //撓癢次數
@property (assign) CGPoint curTickleStart; //獲取開始點
@property (assign) Direction lastDirection;//最近一次方向 

@end 
.m文件

#import "HappyGestureRecognizer.h" 
#import <UIKit/UIGestureRecognizerSubclass.h> 
#define REQUIRED_TICKLES 2 
#define MOVE_AMT_PER_TICKLE 25 

@implementation HappyGestureRecognizer 

//手勢開始時記錄開始坐標點
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
UITouch * touch = [touches anyObject]; 
self.curTickleStart = [touch locationInView:self.view]; 
} 

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

// Make sure we've moved a minimum amount since curTickleStart 
UITouch * touch = [touches anyObject]; 
CGPoint ticklePoint = [touch locationInView:self.view]; //獲取點擊點坐標
CGFloat moveAmt = ticklePoint.x - self.curTickleStart.x; //現在點擊坐標 與 初始坐標
Direction curDirection; 
if (moveAmt < 0) { 
curDirection = DirectionLeft; 
} else { 
curDirection = DirectionRight; 
} 
if (ABS(moveAmt) < MOVE_AMT_PER_TICKLE) return; 

// 確認方向改變了 
if (self.lastDirection == DirectionUnknown || 
(self.lastDirection == DirectionLeft && curDirection == DirectionRight) || 
(self.lastDirection == DirectionRight && curDirection == DirectionLeft)) { 

// 撓癢次數 
self.tickleCount++; 
self.curTickleStart = ticklePoint; 
self.lastDirection = curDirection; 

// 一旦撓癢次數超過指定數,設置手勢為結束狀態 
// 這樣回調函數會被調用。 
if (self.state == UIGestureRecognizerStatePossible && self.tickleCount > REQUIRED_TICKLES) { 
[self setState:UIGestureRecognizerStateEnded]; 
} 
} 

} 


//重置相關數據
- (void)reset { 
self.tickleCount = 0; 
self.curTickleStart = CGPointZero; 
self.lastDirection = DirectionUnknown; 
if (self.state == UIGestureRecognizerStatePossible) { 
[self setState:UIGestureRecognizerStateFailed]; 
} 
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
[self reset]; 
} 

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
[self reset]; 
} 

@end 

調用自定義手勢和系統手勢一樣

- (void)handleHappy:(HappyGestureRecognizer *)recognizer{
[self.hehePlayer play];
}

參考文檔

iOS:事件處理

iOS手勢識別的詳細使用

Demo地址

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,048評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,414評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,169評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,722評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,465評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,823評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,813評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,000評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,554評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,295評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,513評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,722評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,125評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,430評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,237評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,482評論 2 379

推薦閱讀更多精彩內容