iOS 開發(fā)中的常用手勢事件簡述

在開發(fā)過程中,我們?yōu)榱颂岣哂脩趔w驗和App的交互友好性,我們通常會在App中添加一些手勢,來輔助用戶操作.那么這篇文章將簡述一下在開發(fā)過程中我們經(jīng)常用到的手勢事件.

管理手勢事件的類是UIGestureRecognizer,這是一個手勢識別器.而手勢識別器則是一個特殊的觸摸事件.手勢事件是使用了target-action模式(目標-動作模式)設(shè)計的,所以我們在使用的時候指定目標跟動作就好了.

UIGestureRecognizer

UIGestureRecognizer是一個抽象的父類,在開發(fā)過程中我們一般不使用這個類,而是使用其子類.

UIGestureRecognizer的子類

上圖展示了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的子類,比父類多了一個屬性

UIScreenEdgePanGestureRecognizer

同樣是上面的場景,如果我們在view上添加屏幕邊緣手勢,但是首先聲明一下,由于是屏幕邊緣移動,我們知道,屏幕四個邊緣,上,左,下,右.所以我們在添加手勢的時候必須先設(shè)置UIScreenEdgePanGestureRecognizer的edges這個屬性.在這里我設(shè)置為滑動右側(cè)邊緣,視圖移動.

edges這個屬性

它是一個枚舉變量,枚舉元素表示出發(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ù).

UITapGestureRecognizer

我們依然使用上面的場景,為了演示效果,我們設(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)疑問或者疏漏,歡迎留言探討或更正,我將不勝感激.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末月幌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子嚷兔,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件俱两,死亡現(xiàn)場離奇詭異,居然都是意外死亡曹步,警方通過查閱死者的電腦和手機宪彩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人羡蛾,你說我怎么就攤上這事狈惫。” “怎么了活合?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長物赶。 經(jīng)常有香客問我白指,道長,這世上最難降的妖魔是什么酵紫? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任告嘲,我火速辦了婚禮,結(jié)果婚禮上奖地,老公的妹妹穿的比我還像新娘状蜗。我一直安慰自己,他們只是感情好鹉动,可當(dāng)我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布轧坎。 她就那樣靜靜地躺著,像睡著了一般泽示。 火紅的嫁衣襯著肌膚如雪缸血。 梳的紋絲不亂的頭發(fā)上蜜氨,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天,我揣著相機與錄音捎泻,去河邊找鬼飒炎。 笑死,一個胖子當(dāng)著我的面吹牛笆豁,可吹牛的內(nèi)容都是我干的郎汪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼闯狱,長吁一口氣:“原來是場噩夢啊……” “哼煞赢!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起哄孤,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤照筑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后瘦陈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凝危,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年晨逝,在試婚紗的時候發(fā)現(xiàn)自己被綠了蛾默。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡捉貌,死狀恐怖支鸡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情昏翰,我是刑警寧澤苍匆,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布刘急,位于F島的核電站棚菊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏叔汁。R本人自食惡果不足惜统求,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望据块。 院中可真熱鬧码邻,春花似錦、人聲如沸另假。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽边篮。三九已至己莺,卻和暖如春奏甫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背凌受。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工阵子, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人胜蛉。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓挠进,卻偏偏與公主長得像,于是被迫代替她去往敵國和親誊册。 傳聞我的和親對象是個殘疾皇子领突,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容