你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS手勢辨認的詳細運用辦法(拖動,縮放,旋轉,點擊,手勢依賴,自定義手勢)

iOS手勢辨認的詳細運用辦法(拖動,縮放,旋轉,點擊,手勢依賴,自定義手勢)

編輯:IOS開發綜合

手勢辨認在IOS上十分重要,手勢操作挪動設備的重要特征,極大的添加了挪動設備運用便捷性。

1、UIGestureRecognizer引見

手勢辨認在IOS上十分重要,手勢操作挪動設備的重要特征,極大的添加了挪動設備運用便捷性。

IOS零碎在3.2當前,為方便開發這運用一些常用的手勢,提供了UIGestureRecognizer類。手勢辨認UIGestureRecognizer類是個籠統類,上面的子類是詳細的手勢,開發這可以直接運用這些手勢辨認。

UITapGestureRecognizer  UIPinchGestureRecognizer UIRotationGestureRecognizer UISwipeGestureRecognizer UIPanGestureRecognizer UILongPressGestureRecognizer

下面的手勢對應的操作是:

Tap(點一下) Pinch(二指往內或往外撥動,平常常常用到的縮放) Rotation(旋轉) Swipe(滑動,疾速挪動) Pan (拖移,慢速挪動)  LongPress(長按)

UIGestureRecognizer的承繼關系如下:

2、運用手勢的步驟

運用手勢很復雜,分為兩步:

創立手勢實例。當創立手勢時,指定一個回調辦法,當手勢開端,改動、或完畢時,回調辦法被調用。

添加到需求辨認的View中。每個手勢只對應一個View,當屏幕觸摸在View的邊界內時,假如手勢和預定的一樣,那就會回調辦法。

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

建議在真機上運轉這些手勢,模仿器操作不太方便,能夠招致你以為手勢生效。

3、Pan 拖入手勢:

UIImageView *snakeImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"snake.png" />

添加了這幾個手勢後,運轉看效果,順序中的imageView放了一個

    /^\/^\
   _|__|  O|
    \/     /~     \_/ \
     \____|__________/  \
  \_______ \
     `\     \  \
  |     |   \
/ /     \
     /     /   \\
   / /     \ \
  /     /   \  \
     /     /   _----_  \   \
    /     / _-~ ~-_    |   |
   ( (   _-~    _--_    ~-_     _/   |
    \ ~-____-~    _-~    ~-_    ~-_-~    /
~-_ _-~     ~-_  _-~ 
    ~--______-~ ~-___-~

的圖片,在模仿器上拖動是沒問題的。縮放和旋轉有點問題,估量是由於在模仿器上的模仿的兩個接觸點間隔在imageView的邊界外了,所以操作有效果。

建議在真機上運轉這個手勢。

在模仿器上縮放和選擇的操作技巧:

可以把imageView的frame值設置大一點,按住alt鍵,按下觸摸板(不按下不行),這樣就可以旋轉和縮放了。

6、添加第二個ImagView並添加手勢

記住:一個手勢只能添加到一個View,兩個View當然要有兩個手勢的實例了

- (void)viewDidLoad 
{ 
  [super viewDidLoad]; 
 
  UIImageView *snakeImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"snake.png" />

7、拖動(pan手勢)速度(以較快的速度拖放後view有滑行的效果)
如何完成呢?

監視手勢能否完畢 監視觸摸的速度
- (void) handlePan:(UIPanGestureRecognizer*) recognizer 
{ 
  CGPoint translation = [recognizer translationInView:self.view]; 
  recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x, 
                    recognizer.view.center.y + translation.y); 
  [recognizer setTranslation:CGPointZero inView:self.view]; 
   
  if (recognizer.state == UIGestureRecognizerStateEnded) { 
     
    CGPoint velocity = [recognizer velocityInView:self.view]; 
    CGFloat magnitude = sqrtf((velocity.x * velocity.x) + (velocity.y * velocity.y)); 
    CGFloat slideMult = magnitude / 200; 
    NSLog(@"magnitude: %f, slideMult: %f", magnitude, slideMult); 
     
    float slideFactor = 0.1 * slideMult; // Increase for more of a slide 
    CGPoint finalPoint = CGPointMake(recognizer.view.center.x + (velocity.x * slideFactor), 
                     recognizer.view.center.y + (velocity.y * slideFactor)); 
    finalPoint.x = MIN(MAX(finalPoint.x, 0), self.view.bounds.size.width); 
    finalPoint.y = MIN(MAX(finalPoint.y, 0), self.view.bounds.size.height); 
     
    [UIView animateWithDuration:slideFactor*2 delay:0 options:UIViewAnimationOptionCurveEaSEOut animations:^{ 
      recognizer.view.center = finalPoint; 
    } completion:nil]; 
     
  } 

代碼完成解析:

計算速度向量的長度(估量大局部都忘了)這些知識了。 假如速度向量小於200,那就會失掉一個小於的小數,那麼滑行會很短 基於速度和速度要素計算一個起點 確保起點不會跑出父View的邊界 運用UIView動畫使view滑動到起點

運轉後,疾速拖動圖像view放閉會看到view還會在原來的方向滑行一段路。

8、同時觸發兩個view的手勢

手勢之間是互斥的,假如你想同時觸發蛇和龍的view,那麼需求完成協議

UIGestureRecognizerDelegate,

@interface ViewController : UIViewController<UIGestureRecognizerDelegate> 
@end 

並在協議這個辦法裡前往YES。

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

 把self作為代理設置給手勢:

panGestureRecognizer.delegate = self; 
pinchGestureRecognizer.delegate = self; 
rotateRecognizer.delegate = self; 

這樣可以同時拖動或旋轉縮放兩個view了。

9、tap點擊手勢

這裡為了方便看到tap的效果,當點擊一下屏幕時,播放一個聲響。

為了播放聲響,我們參加AVFoundation.framework這個框架。

- (AVAudioPlayer *)loadWav:(NSString *)filename { 
  NSURL * url = [[NSBundle mainBundle] URLForResource:filename withExtension:@"wav"]; 
  NSError * error; 
  AVAudioPlayer * player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error]; 
  if (!player) { 
    NSLog(@"Error loading %@: %@", url, error.localizedDescription); 
  } else { 
    [player prepareToPlay]; 
  } 
  return player; 
} 

我會在最後例子代碼給出完好代碼,添加手勢的步驟和後面一樣的。

#import <UIKit/UIKit.h> 
#import <AVFoundation/AVFoundation.h> 
 
@interface ViewController : UIViewController<UIGestureRecognizerDelegate> 
@property (strong) AVAudioPlayer * chompPlayer; 
@property (strong) AVAudioPlayer * hehePlayer; 
 
@end 
- (void)handleTap:(UITapGestureRecognizer *)recognizer { 
  [self.chompPlayer play]; 
} 

運轉,點一下某個圖,就會播放一個咬東西的聲響。

不過這個點擊播放聲響有點缺陷,就是在漸漸拖動的時分也會播放。這使得兩個手勢重合了。怎樣處理呢?運用手勢的:

requireGestureRecognizerToFail辦法。

10、手勢的依賴性

在viewDidLoad的循環裡添加這段代碼:

[tapRecognizer requireGestureRecognizerToFail:panGestureRecognizer]; 

意思就是,當假如pan手勢失敗,就是沒發作拖動,才會動身tap手勢。這樣假如你有細微的拖動,那就是pan手勢發作了。tap的聲響就不會收回來了。

11、自定義手勢

自定義手勢承繼:UIGestureRecognizer,完成上面的辦法:

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

新建一個類,承繼UIGestureRecognizer,代碼如下:
.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]; 
} 

手勢成功後播放呵呵笑的聲響。

在真機上運轉,按住某個view,疾速左右拖動,就會收回笑的聲響了。

代碼解析:

先獲取起始坐標:curTickleStart

經過和ticklePoint的x值比照,得出以後的放下是向左還是向右。再算出挪動的x的值能否比MOVE_AMT_PER_TICKLE間隔大,假如太則前往。

再判別能否有三次是不同方向的舉措,假如是則手勢完畢,回調。

源代碼:源代碼下載。

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支持本站。

【iOS手勢辨認的詳細運用辦法(拖動,縮放,旋轉,點擊,手勢依賴,自定義手勢)】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved