在開發(fā)過程中,我們?yōu)榱颂岣哂脩趔w驗和App的交互友好性,我們通常會在App中添加一些手勢,來輔助用戶操作.那么這篇文章將簡述一下在開發(fā)過程中我們經(jīng)常用到的手勢事件.
管理手勢事件的類是UIGestureRecognizer,這是一個手勢識別器.而手勢識別器則是一個特殊的觸摸事件.手勢事件是使用了target-action模式(目標-動作模式)設(shè)計的,所以我們在使用的時候指定目標跟動作就好了.
UIGestureRecognizer是一個抽象的父類,在開發(fā)過程中我們一般不使用這個類,而是使用其子類.
上圖展示了UIGestureRecognizer的子類.下面我們就來介紹其中常用的集中手勢事件.
First
我們進行描述之前先假定一個場景,在UIViewController上有一個UIView,設(shè)置顏色為紅色,我們?nèi)∶麨閞edView.現(xiàn)在我們對其進行手勢添加.
UIPanGestureRecognizer平移手勢
現(xiàn)在UIView上面是沒有任何可以被觸發(fā)的事件的,現(xiàn)在我們添加一個平移手勢,讓這張圖片可以在屏幕上任意平移.
此時我們會用到UIGestureRecognizer的子類UIPanGestureRecognizer,在API中有兩個屬性三個方法.其中屬性使用來控制觸摸到UIView 的觸點個數(shù).方法我們通過代碼演示.
代碼如下:
// 我們初始化這個手勢事件,并為它制定一個觸發(fā)方法,就是讓他平移
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panView:)];
//我們將手勢事件添加到view上
[_redView addGestureRecognizer:pan];
平移手勢觸發(fā)的方法為:
- (void)panView:(UIPanGestureRecognizer *)sender{
CGPoint point = [sender translationInView:_redView];
// 以上次位置為標準
sender.view.transform = CGAffineTransformTranslate(sender.view.transform, point.x, point.y);
// 增量值為零
[sender setTranslation:CGPointZero inView:sender.view];
}
我們?yōu)榱四茏屵@個View自由平移,我們設(shè)置為每次移動是以上一次的位置為標準,并且其增量值為零.
UIScreenEdgePanGestureRecognizer屏幕邊緣平移手勢
UIScreenEdgePanGestureRecognizer是UIPanGestureRecognizer的子類,比父類多了一個屬性
同樣是上面的場景,如果我們在view上添加屏幕邊緣手勢,但是首先聲明一下,由于是屏幕邊緣移動,我們知道,屏幕四個邊緣,上,左,下,右.所以我們在添加手勢的時候必須先設(shè)置UIScreenEdgePanGestureRecognizer的edges這個屬性.在這里我設(shè)置為滑動右側(cè)邊緣,視圖移動.
它是一個枚舉變量,枚舉元素表示出發(fā)這個事件需要的手勢位置.
UIScreenEdgePanGestureRecognizer *screenEdgePan = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(screenEdgePanView:)];
// 屬性設(shè)置(設(shè)置邊界)
// 注意,使用屏幕邊緣平移,需要注意兩點
// 1.視圖的位置
// 2.設(shè)置edges屬性
screenEdgePan.edges = UIRectEdgeRight;
[_redView addGestureRecognizer:screenEdgePan];
我們同樣為它添加移動事件.
- (void)screenEdgePanView:(UIScreenEdgePanGestureRecognizer *)sender{
// 計算偏移量
CGPoint point = [sender translationInView:_redView];
// 進行平移
sender.view.transform = CGAffineTransformMakeTranslation(point.x, point.y);
}
UITapGestureRecognizer輕拍事件
輕拍事件有兩個屬性,分別是設(shè)置輕拍時手指的個數(shù)和輕拍的次數(shù).
我們依然使用上面的場景,為了演示效果,我們設(shè)置輕拍手指為兩個,輕拍次數(shù)為兩次.觸發(fā)的事件是隨機變換顏色.
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapView:)];
// 設(shè)置屬性
// 輕拍次數(shù)
tap.numberOfTapsRequired = 2;
// 手指個數(shù)
tap.numberOfTouchesRequired = 2;
// 添加到視圖上
[_redView addGestureRecognizer:tap];
觸發(fā)的事件為:
- (void)tapView:(UITapGestureRecognizer *)sender{
_redView.backgroundColor = [UIColor colorWithRed:arc4random()%256/255.0 green:arc4random()%256/255.0 blue:arc4random()%256/255.0 alpha:0.9];
}
UISwipeGestureRecognizer輕掃手勢
輕掃手勢有兩個屬性:
第一個是設(shè)置輕掃手指的個數(shù),默認是一個.而第二個則是設(shè)置輕掃的方向.我們在view上面添加手勢,手勢觸發(fā)的事件依然是讓view的顏色隨機改變.
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeView:)];
swipe.numberOfTouchesRequired = 1;
// 設(shè)置輕掃方向
// swipe.direction = UISwipeGestureRecognizerDirectionUp;
swipe.direction = UISwipeGestureRecognizerDirectionDown;
// swipe.direction = UISwipeGestureRecognizerDirectionLeft;
// swipe.direction = UISwipeGestureRecognizerDirectionRight;
[_redView addGestureRecognizer:swipe];
觸發(fā)的事件為:
- (void)swipeView:(UISwipeGestureRecognizer *)sender{
_redView.backgroundColor = [UIColor colorWithRed:arc4random()%256/255.0 green:arc4random()%256/255.0 blue:arc4random()%256/255.0 alpha:0.9];
}
UILongPressGestureRecognizer長按手勢
對于長按手勢我們設(shè)置的場景依然跟上面一樣.
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressView:)];
// 最小長按時間
longPress.minimumPressDuration = 2;
[_redView addGestureRecognizer:longPress];
在上面的代碼中,我們通過長按手勢的minimumPressDuration屬性來設(shè)置最小長按時間,也就是設(shè)置了事件longPressView:被觸發(fā)所需要長按的最小時間.
對于長按手勢,我們設(shè)置的事件依舊是隨機改變顏色
- (void)longPressView:(UILongPressGestureRecognizer *)sender{
// 判斷手勢狀態(tài)
if (sender.state == UIGestureRecognizerStateEnded) {
NSLog(@"長按狀態(tài)!");
_redView.backgroundColor = [UIColor colorWithRed:arc4random()%256/255.0 green:arc4random()%256/255.0 blue:arc4random()%256/255.0 alpha:0.9];
}
}
在上面的代碼中我們通過state來判斷手勢的狀態(tài),這個屬性是其父類的屬性,這個屬性中包含了手勢事件從開始到結(jié)束的整個狀態(tài).讀者可以自行參考蘋果官方API,在此就不贅述.以上就是長按手勢.
UIPinchGestureRecognizer捏合手勢
我們都知道當(dāng)我們查看相冊中照片的時候,我們會通過手指的捏合或擴展來進行照片的縮小或放大.我們利用上面的場景對,view進行添加捏合手勢實現(xiàn)類似的功能.
在此,我們可以按住鍵盤的Alt鍵加上鼠標來實現(xiàn)這個場景的模擬.
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchView:)];
// 添加手勢
[_redView addGestureRecognizer:pinch];
相信通過上面的手勢,我們在這個地方已經(jīng)不需要描述事件的觸發(fā)了
- (void)pinchView:(UIPinchGestureRecognizer *)sender{
// 以上一次的為標準
sender.view.transform = CGAffineTransformScale(sender.view.transform, sender.scale, sender.scale);
// 重新設(shè)置縮放比例(1是正掣峭螅縮放, <1 是縮小, >1是放大 )
sender.scale = 1;
}
在這里我們使用了仿射變換來控制view放大縮小的比例.
UIRotationGestureRecognizer旋轉(zhuǎn)手勢
如同上面一樣我們使用同樣的方法來創(chuàng)建手勢,并添加到視圖上.
UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotationView:)];
[_redView addGestureRecognizer:rotation];
我們依舊使用2D仿射變換來實現(xiàn)View的旋轉(zhuǎn)
- (void)rotationView:(UIRotationGestureRecognizer *)sender{
// 兩個參數(shù),以上一次的位置為標準
sender.view.transform = CGAffineTransformRotate(sender.view.transform, sender.rotation);
// 清除增量
sender.rotation = 0.0;
}
其他
在UIView中有一個gestureRecognizers屬性,它表征了View上面的手勢類型,我們可以通過這個屬性來遍歷查看View上面添加的手勢.
for (UIGestureRecognizer *ges in _redView.gestureRecognizers) {
NSLog(@"%@",ges);
}
總結(jié)
以上我們介紹了幾種簡單的手勢.在開發(fā)過程中,我們可以通過添加手勢來提高用戶體驗,增加App對用戶的友好性.相信通過上面的幾種手勢,我們隊iOS開發(fā)中的手勢也有了大致的了解,如果您在閱讀過程中發(fā)現(xiàn)疑問或者疏漏,歡迎留言探討或更正,我將不勝感激.