IOS 定义手势监听器详解,利用 UIGestureRecognizer 进行捏合、旋转、平移、点击、长按手势事件响应
IOS中我們可以通過(guò)UITouch進(jìn)行觸摸事件監(jiān)聽(tīng),但是UITouch實(shí)現(xiàn)捏合、旋轉(zhuǎn)、長(zhǎng)按等手勢(shì)事件監(jiān)聽(tīng)非常麻煩。IOS中提供 UIGestureRecognizer 的子類(lèi)幫我們簡(jiǎn)潔等實(shí)現(xiàn)捏合、旋轉(zhuǎn)等特殊手勢(shì)監(jiān)聽(tīng)。并且一個(gè)視圖可添加多個(gè)不同等手勢(shì)監(jiān)聽(tīng)器。
開(kāi)啟userInteractionEnabled
IOS 中UIView 默認(rèn)是不可響應(yīng)事件的,我們需要開(kāi)啟 userInteractionEnabled 方可進(jìn)行事件響應(yīng)。下面代碼中我們創(chuàng)建了一個(gè)圖片視圖,并且開(kāi)始事件響應(yīng)。UIView 通過(guò) addGestureRecognizer 進(jìn)行添加手勢(shì)監(jiān)聽(tīng)器和 removeGestureRecognizer刪除手勢(shì)監(jiān)聽(tīng)器
// 創(chuàng)建圖片視圖 - (void) creareImg {UIImage* image = [UIImage imageNamed:@"zz.jpeg"];_imageView = [[UIImageView alloc] initWithImage:image];UIScreen* screen = [UIScreen mainScreen];const int width = 200;const int height = 100;const float x = screen.bounds.size.width / 2 - width / 2;const float y = screen.bounds.size.height / 2 - height;_imageView.frame = CGRectMake(x, y, width, height);_imageView.userInteractionEnabled = YES;[self.view addSubview:_imageView]; }了解UIGestrueRecognizer
在開(kāi)始使用自定義手勢(shì)之前我們先了解一下 UIGestrueRecognizer 的,因?yàn)樽远x都是基于 UIGestrueRecognizer 繼承實(shí)現(xiàn)的。 UIGestrueRecognizer 是一個(gè)手勢(shì)監(jiān)聽(tīng)器,它可以設(shè)置多個(gè)手指同時(shí)觸發(fā)觸發(fā)事件等行為。它具有代理協(xié)議 UIGestureRecognizerDelegate 下面我來(lái)看一下它主要的屬性和API、代理方法。
屬性
| state | UIGestureRecognizerState | 當(dāng)前手勢(shì)狀態(tài),可分為手勢(shì)開(kāi)始,手勢(shì)改變,手勢(shì)結(jié)束等等 | |
| enabled | BOOL | 是否啟用 | YES |
| view | UIView | 手勢(shì)監(jiān)聽(tīng)的視圖 | |
| requiresExclusiveTouchType | BOOL | 是否忽略其他手勢(shì)類(lèi)型,設(shè)置為YES將只響應(yīng)一種手勢(shì)類(lèi)型 | NO |
| numberOfTouches | NSUInteger | 多少根手指觸發(fā)手勢(shì) | 1 |
API
- - (instancetype)initWithTarget:(nullable id)target action:(nullable SEL)action 初始化并添加事件監(jiān)聽(tīng)函數(shù)
- - (void)addTarget:(id)target action:(SEL)action 添加事件監(jiān)聽(tīng)函數(shù)
- - (void)removeTarget:(nullable id)target action:(nullable SEL)action 刪除事件監(jiān)聽(tīng)函數(shù)
- - (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer 添加其他手勢(shì)沖突失效器,當(dāng)觸發(fā)當(dāng)前手勢(shì)時(shí),指定的手勢(shì)將失效。
- - (CGPoint)locationInView:(nullable UIView*)view 獲取相對(duì)于指定視圖的坐標(biāo)位置
- - (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(nullable UIView*)view 獲取指定手指相對(duì)指定視圖的坐標(biāo)位置
代理協(xié)議
-
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer 手勢(shì)準(zhǔn)備開(kāi)啟時(shí)候觸發(fā),返回NO則取消手勢(shì)。
-
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 當(dāng)手勢(shì)與其他手勢(shì)同時(shí)發(fā)生識(shí)別時(shí)候觸發(fā),返回YES運(yùn)行兩個(gè)手勢(shì)同時(shí)進(jìn)行,返回NO則阻止同時(shí)識(shí)別。
-
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch 是否給事件接收手指。在手勢(shì)開(kāi)始觸發(fā)事件觸發(fā)前觸發(fā),返回NO可以阻止事件獲取觸摸的手指。
-
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceivePress:(UIPress *)press 是否給按下事件接收手指,在按下手勢(shì)事件觸發(fā)前觸發(fā)。返回NO可阻止事件獲取觸摸的手指。
我們了解清除GestureRecognizer 類(lèi),下面我們來(lái)了解其子類(lèi)手勢(shì)的使用。
UITapGestureRecognizer 點(diǎn)擊手勢(shì)
點(diǎn)擊手勢(shì),可設(shè)置手指數(shù)量、點(diǎn)擊次數(shù)觸發(fā)的手勢(shì)
// 創(chuàng)建點(diǎn)擊手勢(shì) - (void) createTapGes {_imageView.userInteractionEnabled = YES; // 開(kāi)啟響應(yīng)事件屬性UITapGestureRecognizer* tapOneGes = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(big)]; // 創(chuàng)建手勢(shì)tapOneGes.numberOfTapsRequired = 1; // 觸發(fā)事件的點(diǎn)擊次數(shù)tapOneGes.numberOfTouchesRequired = 1; // 觸發(fā)事件的手指數(shù)量[_imageView addGestureRecognizer:tapOneGes]; // 添加手勢(shì)監(jiān)聽(tīng)器 } // 點(diǎn)擊觸發(fā)事件 - (void) big {UIScreen* screen = [UIScreen mainScreen];[UIView beginAnimations:nil context:nil]; // 開(kāi)始布局動(dòng)畫(huà)_imageView.frame = CGRectMake(0, 0, screen.bounds.size.width, screen.bounds.size.height);[UIView commitAnimations]; // 結(jié)束布局動(dòng)畫(huà) }UIPinchGestureRecognizer 捏合手勢(shì)
捏合手勢(shì),表示雙指捏合縮放的手勢(shì)觸發(fā)。常用于對(duì)圖片查看縮放事件監(jiān)聽(tīng)
// 捏合手勢(shì) - (void) createPinchGes {UIPinchGestureRecognizer* pinch = [[UIPinchGestureRecognizer alloc] init]; // 創(chuàng)建手勢(shì)[pinch addTarget:self action:@selector(scale:)]; // 添加事件函數(shù)pinch.delegate = self; // 設(shè)置代理[_imageView addGestureRecognizer:pinch]; // 視圖添加手勢(shì)監(jiān)聽(tīng)器 }- (void) scale: (UIPinchGestureRecognizer*) pinch {UIView* IView = pinch.view; // 獲取監(jiān)聽(tīng)的視圖CGAffineTransform transiform = CGAffineTransformScale(IView.transform, pinch.scale, pinch.scale); // 計(jì)算縮放后的矩陣if (transiform.a < 0.4) { // 縮放小于0.4阻止transiform.a = 0.4;transiform.d = 0.4;}IView.transform = transiform; // 重新設(shè)置矩陣pinch.scale = 1; // 重置縮放矩陣,否則手勢(shì)會(huì)一直累加 }// 添加允許多個(gè)手勢(shì)觸發(fā)代理函數(shù) - (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {return YES; }上面代碼中我們通過(guò)獲取捏合手勢(shì)的scale 屬性獲取用戶(hù)捏合縮放的大小。并且使用內(nèi)置api CGAffineTransformScale 重新計(jì)算了視圖的2D矩陣(矩陣表示圖像變形,可以了解一下圖形學(xué)),注意!最后一步中必須重置手勢(shì)的scale 否則會(huì)一直累加導(dǎo)致計(jì)算矩陣錯(cuò)誤,如果不想重置的話那就需要修改 CGAffineTransformScale的第一個(gè)參數(shù)為基礎(chǔ)矩陣參數(shù)。
UIRotationGestureRecognizer 旋轉(zhuǎn)手勢(shì)
旋轉(zhuǎn)手勢(shì),可獲取用戶(hù)手指旋轉(zhuǎn)的角度。
// 旋轉(zhuǎn)手勢(shì) - (void) createRotateGes {UIRotationGestureRecognizer* rotate = [[UIRotationGestureRecognizer alloc] init];[rotate addTarget:self action:@selector(rotate:)];rotate.delegate = self;[_imageView addGestureRecognizer:rotate]; } // 旋轉(zhuǎn)觸發(fā)事件 - (void) rotate: (UIRotationGestureRecognizer*) rotate {UIView* IView = rotate.view;IView.transform = CGAffineTransformRotate(IView.transform, rotate.rotation); // 重新計(jì)算視圖矩陣rotate.rotation = 0; }UIPanGestureRecognizer 平移手勢(shì)
平移動(dòng)手勢(shì),比較簡(jiǎn)單就是手指移動(dòng)時(shí)候觸發(fā),但是提供平移的位置和平移的速度
// 平移手勢(shì) - (void) createPanGes {UIPanGestureRecognizer* pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];pan.delegate = self;[_imageView addGestureRecognizer:pan]; } - (void) pan: (UIPanGestureRecognizer*)pan {CGPoint speed = [pan velocityInView:_imageView]; // 獲取移動(dòng)速度NSLog(@"x速度= %f, y速度= %f", speed.x, speed.y);CGPoint translation = [pan translationInView:_imageView]; // 獲取移動(dòng)矩陣CGAffineTransform transform = CGAffineTransformTranslate(_imageView.transform, translation.x, translation.y);_imageView.transform = transform; }UILongPressGestureRecognizer 長(zhǎng)按手勢(shì)
長(zhǎng)按對(duì)應(yīng)視圖觸發(fā)手勢(shì),可設(shè)置手指數(shù)量和手指長(zhǎng)按時(shí)間
// 長(zhǎng)按手勢(shì) - (void) createLongPassGes {UILongPressGestureRecognizer* longPass = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(pass:)];longPass.minimumPressDuration = 1; // 設(shè)置長(zhǎng)按觸發(fā)時(shí)間,默認(rèn)0.5[_imageView addGestureRecognizer: longPass]; }- (void)pass: (UILongPressGestureRecognizer*) longPass {if (longPass.state == UIGestureRecognizerStateBegan) {NSLog(@"開(kāi)始長(zhǎng)按");} else if (longPass.state == UIGestureRecognizerStateEnded) {NSLog(@"結(jié)束長(zhǎng)按");} else if (longPass.state == UIGestureRecognizerStateChanged) {NSLog(@"長(zhǎng)按發(fā)生改變");} }UISwipeGestureRecognizer 輕滑手勢(shì)
輕滑手勢(shì),類(lèi)似我們的平移手勢(shì)。但是輕滑不同的是在用戶(hù)快速滑動(dòng)時(shí)候速度,并且只提供滑動(dòng)方向。
// 創(chuàng)建輕滑手勢(shì) - (void) createSwipe {UISwipeGestureRecognizer* swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swiper:)];swipe.direction = UISwipeGestureRecognizerDirectionDown;[_imageView addGestureRecognizer: swipe];swipe.delegate = self; }- (void) swiper: (UISwipeGestureRecognizer*)swiper {NSLog(@"發(fā)生向下滑動(dòng)"); }總結(jié)
以上是生活随笔為你收集整理的IOS 定义手势监听器详解,利用 UIGestureRecognizer 进行捏合、旋转、平移、点击、长按手势事件响应的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 小程序消息服务器webapi,小程序订阅
- 下一篇: c语言输入一个数求因数,【代码】求一个数