亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

iOS事件機制(一)

2019-11-14 18:37:28
字體:
來源:轉載
供稿:網友

本篇內容將圍繞iOS中事件及其傳遞機制進行學習和分析。在iOS中,事件分為三類:

  • 觸控事件(單點、多點觸控以及各種手勢操作)
  • 傳感器事件(重力、加速度傳感器等)
  • 遠程控制事件(遠程遙控iOS設備多媒體播放等)

這三類事件共同構成了iOS設備豐富的操作方式和使用體驗,本次就首先來針對第一類事件:觸控事件,進行學習和分析。

Gesture Recognizers

Gesture Recognizers是一類手勢識別器對象,它可以附屬在你指定的View上,并且為其設定指定的手勢操作,例如是點擊、滑動或者是拖拽。當觸控事件 發生時,設置了Gesture Recognizers的View會先通過識別器去攔截觸控事件,如果該觸控事件是事先為View設定的觸控監聽事件,那么Gesture Recognizers將會發送動作消息給目標處理對象,目標處理對象則對這次觸控事件進行處理,先看看如下流程圖。

在iOS中,View就是我們在屏幕上看到的各種UI控件,當一個觸控事件發生時,Gesture Recognizers會先獲取到指定的事件,然后發送動作消息(action message)給目標對象(target),目標對象就是ViewController,在ViewController中通過事件方法完成對該事件的處理。Gesture Recognizers能設置諸如單擊、滑動、拖拽等事件,通過Action-Target這種設計模式,好處是能動態為View添加各種事件監聽,而不用去實現一個View的子類去完成這些功能。

以上過程就是我們在開發中在方法中常見的設置action和設置target,例如為UIButton設置監聽事件等。

常用手勢識別類

在UIKit框架中,系統為我們事先定義好了一些常用的手勢識別器,包括點擊、雙指縮放、拖拽、滑動、旋轉以及長按。通過這些手勢識別器我們可以構造豐富的操作方式。

在上表中可以看到,UIKit框架中已經提供了諸如UITapGestureRecognizer在內的六種手勢識別器,如果你需要實現自定義的手勢識別器,也可以通過繼承UIGestureRecognizer類并重寫其中的方法來完成,這里我們就不詳細討論了。

每一個Gesture Recognizer關聯一個View,但是一個View可以關聯多個Gesture Recognizer,因為一個View可能還能響應多種觸控操作方式。當一個觸控事件發生時,Gesture Recognizer接收一個動作消息要先于View本身,結果就是Gesture Recognizer作為View處理觸控事件的代表,或者叫代理。當Gesture Recognizer接收到指定的事件時,它就會發送一條動作消息(action message)給ViewController并處理。

連續和不連續動作

觸控動作同時分為連續動作(continuous)和不連續動作(discrete),連續動作例如滑動和拖拽,它會持續一小段時間,而不連續動作例如單擊,它瞬間就會完成,在這兩類事件的處理上又稍有不同。對于不連續動作,Gesture Recognizer只會給ViewContoller發送一個單一的動作消息(action message),而對于連續動作,Gesture Recognizer會發送多條動作消息給ViewController,直到所有的事件都結束。

為一個View添加GestureRecognizer有兩種方式,一種是通過InterfaceBuilder實現,另一種就是通過代碼實現,我們看看通過代碼來如何實現。

MyViewContoller.m

123456789101112131415
- (void)viewDidLoad {     [super viewDidLoad];     // 創建并初始化手勢對象     UITapGestureRecognizer *taPRecognizer = [[UITapGestureRecognizer alloc]          initWithTarget:self action:@selector(respondToTapGesture:)];     // 指定操作為單擊一次     tapRecognizer.numberOfTapsRequired = 1;     // 為當前View添加GestureRecognizer     [self.view addGestureRecognizer:tapRecognizer];     // ...}

通過上述代碼,我們實現了為當前MyViewController的View添加一個單擊事件,首先構造了UITapGestureRecognizer對象,指定了target為當前ViewController本身,action就是后面自己實現的處理方法,這里就呼應了前文提到的Action-Target模式。

在事件處理過程中,這兩種方式所處的狀態又各有不同,首先,所有的觸控事件最開始都是處于可用狀態(Possible),對應UIKit里面的UIGestureRecognizerStatePossible類,如果是不連續動作事件,則狀態只會從Possible轉變為已識別狀態(Recognized,UIGestureRecognizerStateRecognized)或者是失敗狀態(Failed,UIGestureRecognizerStateFailed)。例如一次成功的單擊動作,就對應了Possible-Recognized這個過程。

如果是連續動作事件,如果事件沒有失敗并且連續動作的第一個動作被成功識別(Recognized),則從Possible狀態轉移到Began(UIGestureRecognizerStateBegan)狀態,這里表示連續動作的開始,接著會轉變為Changed(UIGestureRecognizerStateChanged)狀態,在這個狀態下會不斷循環的處理連續動作,直到動作執行完成變轉變為Recognized已識別狀態,最終該動作會處于完成狀態(UIGestureRecognizerStateEnded),另外,連續動作事件的處理狀態會從Changed狀態轉變為Canceled(UIGestureRecognizerStateCancelled)狀態,原因是識別器認為當前的動作已經不匹配當初對事件的設定了。每個動作狀態的變化,Gesture Recognizer都會發送消息(action message)給Target,也就是ViewController,它可以根據這些動作消息進行相應的處理。例如一次成功的滑動手勢動作就包括按下、移動、抬起的過程,分別對應了Possible-Began-Changed-Recognized這個過程。

UITouch & UIEvent

在屏幕上的每一次動作事件都是一次Touch,在iOS中用UITouch對象表示每一次的觸控,多個Touch組成一次Event,用UIEvent來表示一次事件對象。

在上述過程中,完成了一次雙指縮放的事件動作,每一次手指狀態的變化都對應事件動作處理過程中得一個階段。通過Began-Moved-Ended這幾個階段的動作(Touch)共同構成了一次事件(Event)。在事件響應對象UIResponder中有對應的方法來分別處理這幾個階段的事件。

  • touchesBegan:withEvent:
  • touchesMoved:withEvent:
  • touchesEnded:withEvent:
  • touchesCancelled:withEvent:

后面的參數分別對應UITouchPhaseBegan、UITouchPhaseMoved、UITouchPhaseEnded、UITouchPhaseCancelled這幾個類。用來表示不同階段的狀態。

事件傳遞

如上圖,iOS中事件傳遞首先從App(UIapplication)開始,接著傳遞到Window(UIWindow),在接著往下傳遞到View之前,Window會將事件交給GestureRecognizer,如果在此期間,GestureRecognizer識別了傳遞過來的事件,則該事件將不會繼續傳遞到View去,而是像我們之前說的那樣交給Target(ViewController)進行處理。

響應者鏈(Responder Chain)

通常,一個iOS應用中,在一塊屏幕上通常有很多的UI控件,也就是有很多的View,那么當一個事件發生時,如何來確定是哪個View響應了這個事件呢,接下來我們就一起來看看。

尋找hit-test view

什么是hit-test view呢?簡單來說就是你觸發事件所在的那個View,尋找hit-test view的過程就叫做Hit-Testing。那么,系統是如何來執行Hit-Testing呢,首先假設現在有如下這么一個UI布局,一種有ABCDE五個View。

假設一個單擊事件發生在了View D里面,系統首先會從最頂層的View A開始尋找,發現事件是在View A或者其子類里面,那么接著從B和C找,發現事件是在C或者其子類里面,那么接著到C里面找,這時發現事件是在D里面,并且D已經沒有子類了,那么hit-test view就是View D啦。

響應者對象(Responsder Object)

響應者對象是能夠響應并且處理事件的對象,UIResponder是所有響應者對象的父類,包括UIApplication、UIView和UIViewController都是UIResponder的子類。也就意味著所有的View和ViewController都是響應者對象。

第一響應者(First Responder)

第一響應者是第一個接收事件的View對象,我們在Xcode的Interface Builder畫視圖時,可以看到視圖結構中就有First Responder。

這里的First Responder就是UIApplication了。另外,我們可以控制一個View讓其成為First Responder,通過實現 canBecomeFirstResponder方法并返回YES可以使當前View成為第一響應者,或者調用View的becomeFirstResponder方法也可以,例如當UITextField調用該方法時會彈出鍵盤進行輸入,此時輸入框控件就是第一響應者。

事件傳遞機制

如上所說,,如果hit-test view不能處理當前事件,那么事件將會沿著響應者鏈(Responder Chain)進行傳遞,知道遇到能處理該事件的響應者(Responsder Object)。通過下圖,我們來看看兩種不同情況下得事件傳遞機制。

左邊的情況,接收事件的initial view如果不能處理該事件并且她不是頂層的View,則事件會往它的父View進行傳遞。initial view的父View獲取事件后如果仍不能處理,則繼續往上傳遞,循環這個過程。如果頂層的View還是不能處理這個事件的話,則會將事件傳遞給它們的ViewController,如果ViewController也不能處理,則傳遞給Window(UIWindow),此時Window不能處理的話就將事件傳遞給Application(UIApplication),最后如果連Application也不能處理,則廢棄該事件。

右邊圖的流程唯一不同就在于,如果當前的ViewController是由層級關系的,那么當子ViewController不能處理事件時,它會將事件繼續往上傳遞,直到傳遞到其Root ViewController,后面的流程就跟之前分析的一樣了。

這就是事件響應者鏈的傳遞機制,通過這些內容,我們可以更深入的了解事件在iOS中得傳遞機制,對我們在實際開發中更好的理解事件操作的原理有很大的幫助,也對我們實現復雜布局進行事件處理時增添了多一份的理解。

總結

通過前面的內容分析,我們已經學習并了解了如下內容:

  • Gesture Recognizers,是用來控制手勢識別的過程和方法,并且其通過Action-Target模式與ViewController的通信的方式。連續和不連續手勢動作情況下GestureRecognizer的狀態轉變。
  • UITouch和UIEvent對象,他們都是UIKit中來進行事件處理的對象,多個UITouch對象構成一個UIEvent對象,重寫相應的方法可以控制和處理事件各個階段的操作。
  • 系尋找hit-test view的方式、事件傳遞機、制響應者鏈

后記:本篇是iOS事件傳遞機制的上篇,下篇將繼續討論多點觸控事件和手勢操作的內容!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
中文字幕日韩精品有码视频| 欧美激情三级免费| 欧美激情视频一区| 中文字幕9999| 色综合久久天天综线观看| 亚洲福利影片在线| 欧美福利视频在线观看| 在线国产精品播放| 日韩有码在线电影| 欧美在线观看一区二区三区| 国产精品久久不能| 精品激情国产视频| 欧美猛男性生活免费| 午夜免费日韩视频| 最近2019年日本中文免费字幕| 久久久久久这里只有精品| 欧美在线日韩在线| 日本不卡高字幕在线2019| 亚洲人成网站在线播| 亚洲欧洲在线免费| 日韩欧美亚洲范冰冰与中字| 中文精品99久久国产香蕉| 国产69久久精品成人| 日韩电影在线观看中文字幕| 欧美激情videos| 欧美激情一区二区三区在线视频观看| 亚洲国产精品电影在线观看| 这里只有精品视频| 欧美与黑人午夜性猛交久久久| 欧美成人性生活| 亚洲成av人乱码色午夜| 91丝袜美腿美女视频网站| xxxxx91麻豆| 国产成人久久精品| 久久影视电视剧凤归四时歌| 久久免费少妇高潮久久精品99| 中文字幕日韩在线播放| 亚洲精品av在线| 亚洲国产精品va在线观看黑人| 永久555www成人免费| 狠狠躁夜夜躁人人爽超碰91| 国产精品电影久久久久电影网| 久久视频在线视频| 这里只有精品久久| 国产精品观看在线亚洲人成网| 色偷偷偷亚洲综合网另类| 国产精品视频精品| 欧美精品久久久久久久久| 亚洲无限乱码一二三四麻| 欧美另类高清videos| 国产亚洲欧美另类中文| 国产一区二区三区直播精品电影| 中文字幕精品久久| 亚洲福利视频免费观看| 欧美孕妇毛茸茸xxxx| 欧美贵妇videos办公室| 亚洲自拍中文字幕| 欧美成人国产va精品日本一级| 韩国三级电影久久久久久| 久久久国产视频| 欧美乱人伦中文字幕在线| 国产一区二区三区在线播放免费观看| 日韩欧美在线视频免费观看| 欧美精品在线极品| 日韩精品中文字幕在线播放| 中国日韩欧美久久久久久久久| 欧美一级淫片播放口| 亚洲人成电影在线观看天堂色| 亚洲美女福利视频网站| 精品高清美女精品国产区| 国产精品高潮呻吟久久av黑人| 久久亚洲成人精品| 国产日韩欧美在线观看| 川上优av一区二区线观看| 久久五月情影视| 日韩美女视频在线观看| 欧美黄色成人网| 91九色国产社区在线观看| 亚洲一区二区三区sesese| 最近2019年手机中文字幕| 亚洲丝袜av一区| 欧美激情啊啊啊| 91亚洲va在线va天堂va国| 91在线中文字幕| 91亚洲国产精品| 欧美丰满少妇xxxxx做受| 亚洲精品久久久久| 亚洲第一区在线| 亚洲精品一区二区三区不| 伊人伊成久久人综合网站| 国产专区欧美专区| 亚洲精品国产精品自产a区红杏吧| 色哟哟网站入口亚洲精品| 九九视频直播综合网| 欧美理论在线观看| 性欧美长视频免费观看不卡| 亚洲视频在线播放| 91九色国产在线| 亚洲丁香婷深爱综合| 日韩免费黄色av| 欧洲亚洲在线视频| 久久久久免费精品国产| 日韩成人在线视频观看| 欧美激情在线一区| 精品成人在线视频| 欧美最猛性xxxxx亚洲精品| 精品一区二区三区四区在线| 国产精品入口免费视频一| 久久久女人电视剧免费播放下载| 国产精品久久久久99| 91国产视频在线| 国产精品igao视频| 国产婷婷97碰碰久久人人蜜臀| 精品亚洲国产成av人片传媒| 国产mv免费观看入口亚洲| 亚洲色图激情小说| 日韩成人在线视频观看| 日韩欧美成人精品| 永久免费看mv网站入口亚洲| 亚洲国产一区自拍| 日韩欧美有码在线| 日韩中文字幕视频在线| 欧美精品久久久久久久免费观看| 福利二区91精品bt7086| 亚洲www在线观看| 亚洲电影免费观看高清| 亚洲欧美精品suv| 亚洲天堂网站在线观看视频| 韩国精品美女www爽爽爽视频| 久久色精品视频| 欧美亚洲第一区| 色琪琪综合男人的天堂aⅴ视频| 欧洲亚洲妇女av| 国语自产偷拍精品视频偷| 亚洲男人天堂手机在线| 久国内精品在线| 久久精品成人动漫| 国产精品r级在线| 久久99久久99精品免观看粉嫩| 亚洲丁香久久久| 日韩在线视频网| 日韩精品在线免费播放| 2019中文字幕在线观看| 亚洲电影免费观看高清| 久久久久久久久爱| 国产精品高清在线观看| 国产精品久久久久久久7电影| 久久999免费视频| 精品久久久国产| 亚洲美女中文字幕| 日韩av色综合| 米奇精品一区二区三区在线观看| 国产精品女视频| 日韩欧美国产免费播放| 欧美野外wwwxxx| 成人精品一区二区三区| 国产一区欧美二区三区| 国产亚洲精品美女| 亚洲精品福利免费在线观看| 91精品在线观看视频| 91免费视频网站| 亚洲国产天堂久久国产91| 成人综合网网址| 97高清免费视频|