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