實(shí)戰(zhàn)1.2-利用手勢識(shí)別器,實(shí)現(xiàn)視圖的手勢控制

title: 實(shí)戰(zhàn)1.2-利用手勢識(shí)別器,實(shí)現(xiàn)視圖的手勢控制

知識(shí)預(yù)備

  1. 什么是仿射變換?

從視覺效果上來理解,仿射變換是通過一系列原子變換復(fù)合而來的變換。包括:平移(Translation)、縮放(Scale)、翻轉(zhuǎn)(Flip)、旋轉(zhuǎn)(Rotation)和錯(cuò)切(Shear)(圖像的錯(cuò)切實(shí)際上是平面景物在投影平面上的非垂直投影)。

  1. iOS 視圖的 frame 和 bounds 屬性的區(qū)別

frame 描述了該視圖在父視圖坐標(biāo)系統(tǒng)中的位置和大小,其參照點(diǎn)是父視圖的坐標(biāo)系統(tǒng)。
bounds 描述了該視圖在本地坐標(biāo)系統(tǒng)中的位置和大小,其參照點(diǎn)是該視圖自己的坐標(biāo)系統(tǒng)。

示例

如果還有疑惑,可以點(diǎn)擊下方鏈接,這篇博文確切地解釋了區(qū)別所在。
iOS 視圖的 frame 和 bounds 屬性的區(qū)別

3.UIGestureRecognizerState 的參數(shù)值(狀態(tài))

  • UIGestureRecognizerStatePossible : 手勢識(shí)別器還沒有識(shí)別出手勢,但是可能正在估算觸摸事件(touches event),還處在判斷階段。這個(gè)狀態(tài)是手勢識(shí)別器的默認(rèn)狀態(tài)。

  • UIGestureRecognizerStateBegan : 手勢識(shí)別器已經(jīng)接收到了一系列觸摸并且識(shí)別出了它屬于哪個(gè)手勢。響應(yīng)方法在下一個(gè)運(yùn)行周期被調(diào)用。

  • UIGestureRecognizerStateChanged : 手勢識(shí)別器已經(jīng)接收到了一系列觸摸并且識(shí)別出手勢發(fā)生了改變。響應(yīng)方法在下一個(gè)運(yùn)行周期被調(diào)用。

  • UIGestureRecognizerStateEnded : 手勢識(shí)別器已經(jīng)接收到了一系列觸摸并且識(shí)別出手勢剛剛結(jié)束。響應(yīng)方法在下一個(gè)運(yùn)行周期被調(diào)用,并且把手勢狀態(tài)的值重新置為 UIGestureRecognizerStatePossible。

  • UIGestureRecognizerStateCancelled : 手勢識(shí)別器已經(jīng)接收到了一系列觸摸并且識(shí)別出手勢突然中斷。響應(yīng)方法在下一個(gè)運(yùn)行周期被調(diào)用,并且把手勢狀態(tài)的值重新置為 UIGestureRecognizerStatePossible。

  • UIGestureRecognizerStateFailed : 手勢識(shí)別器已經(jīng)接收到了一系列多點(diǎn)觸控,但是與識(shí)別器認(rèn)識(shí)的手勢匹配失敗(識(shí)別不出來)。無響應(yīng)方法。把手勢狀態(tài)的值重新置為 UIGestureRecognizerStatePossible。

  • UIGestureRecognizerStateRecognized : 手勢識(shí)別器已經(jīng)接收到了一系列多點(diǎn)觸控,并且識(shí)別器識(shí)別出該手勢。響應(yīng)方法在下一個(gè)運(yùn)行周期被調(diào)用,并且把手勢狀態(tài)的值重新置為 UIGestureRecognizerStatePossible。

實(shí)戰(zhàn)

  1. 創(chuàng)建工程步驟請參照 實(shí)戰(zhàn)1中的前幾步。

  2. 在工程中創(chuàng)建一個(gè) MyImageView 視圖類,繼承自 UIImageView。

  3. 首先為我們創(chuàng)建的視圖類進(jìn)行初始化方法的編寫,在 MyImageView.m 文件中:

     static int count;
     
     @implementation MyImageView {
         
         CGPoint previousLocation;
         UIPanGestureRecognizer *panGestureRecognizer;
     }
     
     #pragma mark - initialization
     
     - (id) initWithImage:(UIImage *)image {
         
         self = [super initWithImage:image];
         
         if (self) {
         
             self.userInteractionEnabled = YES;
             
             // 在視圖被初始化的過程中,創(chuàng)建一個(gè) 拖動(dòng)手勢識(shí)別器
             // 應(yīng)用 target-action 模式,以該類為目標(biāo)對象,如果手勢被觸發(fā),handlePan: 方法會(huì)被調(diào)用
             panGestureRecognizer = [[UIPanGestureRecognizer alloc]
                                     initWithTarget:self action:@selector(handlePan:)];
             
             // 該類的實(shí)例對象能夠被 拖動(dòng)手勢識(shí)別器 所識(shí)別
             self.gestureRecognizers = @[panGestureRecognizer];
         }
         
         return self;
         
     }
     
     - (id) init {
         
             // 圖片文件的名稱為 blue.png
         return [self initWithImage:[UIImage imageNamed:@"blue"]];
     }
    
     #pragma mark - touches mothods are called
     
     // 當(dāng)該類的實(shí)例對象被觸碰的時(shí)候,該方法會(huì)被觸發(fā)
     - (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
     
          [self.superview bringSubviewToFront:self];
         
         // 視圖中心點(diǎn)
          previousLocation = self.center;
         
     }
     
     #pragma mark - selector handlePan:
     
     - (void) handlePan:(UIPanGestureRecognizer *) gestureRecognizer {
         
         // print 該方法的運(yùn)行次數(shù)
         NSLog(@"%i", ++count);
         
         // 根據(jù)視圖的仿射變換來獲取偏移量
         CGPoint translation = [gestureRecognizer translationInView:self.superview];
         
         // 重置視圖中心點(diǎn)
         self.center = CGPointMake(previousLocation.x + translation.x, previousLocation.y + translation.y);
         
     }
    
  4. 在 ViewController.h 文件中聲明屬性:

     @class MyImageView;
    
     @interface ViewController : UIViewController
    
     @property (nonatomic, strong) MyImageView *myImageView;
    
  5. 在 ViewController.m 文件中導(dǎo)入頭文件(#import "MyImageView.h")并寫入代碼:

     - (void)viewDidLoad {
         [super viewDidLoad];
         
         // 創(chuàng)建類實(shí)例并且添加視圖
         _myImageView = [[MyImageView alloc] initWithImage:[UIImage imageNamed:@"blue"]];
         
         [self.view addSubview:_myImageView];
         
     }
    
  6. 運(yùn)行結(jié)果: 視圖能夠響應(yīng)拖動(dòng)手勢,在屏幕上被拖動(dòng)。控制臺(tái)顯示結(jié)果標(biāo)明, handlePan: 方法在拖動(dòng)手勢進(jìn)行過程中,一直都在被調(diào)用,直至手勢停止。
    console

總結(jié):

** 為了讓自定義視圖能夠響應(yīng)手勢,我們在創(chuàng)建并且初始化視圖類實(shí)例的時(shí)候,就應(yīng)該創(chuàng)建響應(yīng)的手勢識(shí)別器及其會(huì)響應(yīng)的方法,當(dāng)手勢在進(jìn)行過程中時(shí),響應(yīng)方法被反復(fù)調(diào)用,直至手勢停止。為了讓視圖能夠跟隨手勢移動(dòng),我們只需根據(jù)視圖先前的中心位置和被拖動(dòng)以后的偏移位置來重新設(shè)定視圖的中心位置即可。
**

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,182評論 6 543
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,489評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,290評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,776評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,510評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,866評論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,860評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,036評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,585評論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,331評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,536評論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,058評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,754評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,154評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,469評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,273評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,505評論 2 379

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