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

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

事件處理原理(IOS篇)bysixleaves

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

前言

了解IOS事件處理的本質關鍵要先掌握幾個概念。首先是事件的派發(Event Delivery)的過程, 一個是響應者鏈條如何構成。

事件的派發:

Q1: 你有沒有想過,如果你一個屏幕中有多個的View。當你點擊某個view的時候, 這個點擊事件是如何傳遞到這個View身上的?

S1: 正是因為當我們點擊屏幕上某個點的時候, IOS會檢查到手指觸摸操作(Touch),并生產一個UITouch對象,將其打包成一個UIEvent對象。然后將其放入當前活動的application事件對列, UIApplication會從事件對列中按照對列的順序,取出觸摸事件傳遞給UIWindow處理,UIWindow對象會使用hitTest:withEvent:方法來尋找此次的觸摸操作初始點所在的最深層次的視圖(View).**即調用hitTest:withEvent會返回該觸摸點所在的最深層次的視圖。 **

Q2:hitTest:withEvent如何實現找到最深層次的視圖,也就是目的視圖。

S2: 這就要說到深度優先搜索算法,hitTest:withEvent正是基于深度優先搜索的方式來找到最深層次的視圖對象。所以我來介紹以下深度優先算法的思想, 要理解該思想, 你首先要有樹結構這一概念(參見數據結構中的樹結構)。該思想是從根節點開始遍歷樹,而遍歷的順序是采用把下一個子節點當做當前根節點繼續遍歷。所以其是先遍歷到最樹的最深的一層再層層回朔到根節點,接著在把另外一個子節點當做當前根節點繼續遍歷。正是基于這種思想, 所以我們可以很方便的采用遞歸來實現。如果還是不理解,有兩種辦法幫助你,一種是去找深度優先的動態圖,一看就懂了我說的。另外一種方法是去復習數據結構與算法。

Q3:既然hitTest:withEvent利用了深度優先的思想來做,并采用遞歸的做法來做。那么遞歸結束的條件是啥?也就是說什么條件下事件不會向下派發?

S3:根據官方文檔給出的條件是(hidden == YES || userInteractionEnabled == YES || alpha < 0.01 || subViews.bounds > subViews.superView.bounds)

何為響應者鏈條

Q4: 也許你經常聽別人在說響應者鏈條,但是還是云里霧里。這邊我就給你解釋下

S4: 首先先明確何為響應者? ===> 在ios開發中繼承自UIResponder的類或子類就是響應者,顧明思意,響應者是用來相應事件的(觸摸事件、運動事件、遠程遙控事件)。所以所謂的響應者鏈條就是一系列響應者構成的層次結構。

Q5: 那么響應者鏈條是如何表示這種層次結構的呢?

S5: 響應者鏈條是通過nextResponder方法的返回值來組成這種層次結構的 ,蘋果有一段官方解釋如下:

The UIResponder class does not store or set the next responder automatically, instead returning nil by default. Subclasses must override this method to set the next responder. UIView implements this method by returning the UIViewController object that manages it (if it has one) or its superview (if it doesn’t); UIViewController implements the method by returning its view’s superview; UIWindow returns the application object, and UIApplication returns nil.

也就是說,響應者對象是不會自動設置和存儲下一個響應者,默認情況下是直接返回nil。而繼承自UIResponder的子類必須重寫這個方法來設置下一個響應者,并且需要遵循如下規范

    1. 如果子類是UIView,那么其getter方法的nextResponder必須返回其UIViewController對象。       如果不存在控制器,則返回其父視圖對象。    2. 如果子類是UIViewController對象, 那么重寫的nextResponder方法必須返回其view視圖的父視圖對象。    3. 如果子類是UIWindow對象,那么重寫的nextResponder方法返回的是application對象    4. 如果子類是UIApplication對象,那么重寫的nextResponder方法,返回nil。

通過上述規范,結合下圖,你應該能很容易理解所謂的響應者鏈條如何構成:

Q6: 疑問,假設我有一個自定義的SWPButton,而且給其設置了連線action(也就是點擊按鈕后回調的函數)。我們知道當我們點擊按鈕的時候系統會捕捉到這個事件,并將其派發下來。那么我們如何做到讓按鈕不響應這個action而是只響應這個事件。

  • S6: 本質上系統默認實現的touchesBegan:withEvent:方法是做了兩件事件, 或者說有繼承子UIResponder的系統定義的類,都默認實現了以下兩件事情
    • 第一件事情是: 調用[super touchesBegan:withEvent]讓父類有機會來處理該事件。 同時傳遞了事件,讓父類能根據事件處理相應的action回調,比如父類會在這里面處理action(也就是點擊按鈕時候的回調)
    • 第二件事情是: 拋給上一個響應者,讓上一個響應者也能處理該事件。同時傳遞了該事件。這兩個是不一樣的,前者是針對父類,后者是針對響應者鏈條。二者缺一不可。再者,有的人會說只要實現了[super toucesBegan:withEveent]就會將事件拋開上一個響應者,這是不嚴謹的說法。因為這是因為系統已經為所有繼承自UIResponder的子類,做了上面那兩件事件。比如 ,當你自定義一個SWPButton該類繼承自UIButton,那么當你重寫touchesBegan方法的時候,在你們調用[super touchesBegan:withEvent]這個方法時候,系統自定義的UIButton類已經具備這個功能,所以其能完成向上拋。而當我們定義一個純潔的SWPButton直接繼承自UIResponder, 那么我們必須自己實現向上拋這個事情,而不是只調用[super touchesBegan:withEvent]。
      華麗的分割線,以下是度對Q6的解答因為我們繼承自UIButton,所以要截斷該action的回調,我們只需重寫touchesBegan:withEvent方法。并且不做第一件事件,那么也就不會將事件傳遞給Button對象,button也就無法響應相應的action。
#import "SWPButton.h"@implementation SWPButton- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {        [self.nextResponder touchesBegan:touches withEvent:event];}@end

所以此時如果你點擊按鈕, 其會先調用這個自定義按鈕的touchesBegan, 因為點擊事件傳遞到了button身上,所以會調用touchesBegan來響應該事件,但是該事件不在交給父類處理,所以不會調用action。只會繼續將其拋給上一個響應者。

放大招(根據View來找到其所在控制器):

@implementation UIView (ParentController)-(UIViewController*)parentController{    UIResponder *responder = [self nextResponder];    while (responder) {    if ([responder isKindOfClass:[UIViewController class]]) {        return (UIViewController*)responder;    }    responder = [responder nextResponder];    }    return nil;}@end
思路很簡單,就是利用響應者鏈條來尋找UIViewController.那么這個UIView的上一個響應者只有兩種情況,一種是依然是一個UIView對象或其子對象,也就是說它是這個UIView的子View。一種是這個  UIView的控制器。所以我們才需要循環判斷,然后不斷找(循環),直到第一次找到的控制器,就是這個UIView所在的控制器。如果找不到,就返回nil。

是不是更加理解你事件派發的過程,所謂的事件派發過程,其實就是尋找最合適的視圖的時候,事件隨著這個尋找過程,不斷傳遞。為什么要傳遞UIEvent呢?因為通過它給以獲得Touch對象,而通過Touch對象我們可以獲得初始觸摸點。也就是說hitTest:withEvent主要實現的功能是,傳遞事件,找到最合適的視圖。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲理论在线a中文字幕| 在线观看日韩欧美| 午夜精品久久久久久久99热浪潮| 国产精品福利久久久| 欧美精品videosex性欧美| 中文字幕欧美专区| 中文字幕在线成人| 久久国产精品偷| 亚洲欧美日韩成人| 亚洲国产欧美在线成人app| 国产日韩中文字幕| 国产精品久久久久久网站| 久久精品国产一区二区电影| 九九视频这里只有精品| 美乳少妇欧美精品| 精品久久久久人成| 精品国产依人香蕉在线精品| 亚洲精品v天堂中文字幕| 国产精品男人的天堂| 久久影院在线观看| 国产精品精品视频| 日韩在线观看免费全| 亚洲情综合五月天| 亚洲视频在线视频| 国产丝袜视频一区| 91国内揄拍国内精品对白| 韩国视频理论视频久久| 国产精品久久久久91| 欧美精品生活片| 欧美一级视频一区二区| 日韩亚洲第一页| 热99精品里视频精品| 91精品国产成人| 亚洲一区久久久| 国产精品久久久久久av福利| 国产一区二区三区在线免费观看| 欧美一级成年大片在线观看| 国产精品第七十二页| 91免费精品国偷自产在线| 中国china体内裑精亚洲片| 亚洲欧美日韩一区二区在线| 欧美日韩国产中文字幕| 国产精品视频免费观看www| 欧美激情一级二级| 日本精品va在线观看| 欧美裸体xxxx极品少妇| 日韩欧美中文字幕在线播放| 日韩精品中文字幕久久臀| 欧美激情在线一区| 亚洲网站在线播放| 欧美日韩国产va另类| 欧美激情按摩在线| 韩国日本不卡在线| 亚洲人线精品午夜| 日韩免费高清在线观看| 激情av一区二区| 最新国产成人av网站网址麻豆| 庆余年2免费日韩剧观看大牛| 精品性高朝久久久久久久| 欧美日韩福利在线观看| 久久久久久久一区二区| 亚洲一区二区久久| 日韩av不卡在线| 成人免费直播live| 国产精品男人的天堂| 欧美日韩另类在线| 一道本无吗dⅴd在线播放一区| 亚洲最大激情中文字幕| 欧美国产精品va在线观看| 俺也去精品视频在线观看| 欧美激情视频一区| 97香蕉超级碰碰久久免费的优势| 欧美电影在线观看网站| 欧美激情亚洲国产| 九九九久久久久久| 久久精品久久久久| 北条麻妃在线一区二区| 成人黄色免费网站在线观看| 亚洲欧美视频在线| 2018中文字幕一区二区三区| 国产在线98福利播放视频| 欧美激情一区二区三区在线视频观看| 韩国视频理论视频久久| 亚洲已满18点击进入在线看片| 亚洲欧美日韩国产中文专区| 久久久在线免费观看| 久久久久久高潮国产精品视| 这里只有精品久久| 主播福利视频一区| 成人欧美在线视频| 久久69精品久久久久久久电影好| 久久久精品一区二区| 美女啪啪无遮挡免费久久网站| 欧美特黄级在线| 国产在线999| 欧洲美女7788成人免费视频| 精品成人国产在线观看男人呻吟| 亚洲自拍欧美另类| 亚洲va欧美va国产综合久久| 欧美日韩性视频在线| 国产精品偷伦一区二区| 日本午夜人人精品| 国产精品精品国产| 日本成人在线视频网址| 国产精品久久久久久av福利| 8090成年在线看片午夜| 久久视频精品在线| 中文综合在线观看| 国产婷婷成人久久av免费高清| 91网站在线看| 日韩中文字幕精品| 国产精品高潮在线| 成人黄色短视频在线观看| 欧洲亚洲免费视频| 国产午夜精品久久久| 亚洲91精品在线观看| 亚洲福利在线看| 国语对白做受69| 欧美激情亚洲另类| 亚洲视频国产视频| 国产精品欧美亚洲777777| 45www国产精品网站| 成人精品在线观看| 色噜噜国产精品视频一区二区| 亚洲欧美三级在线| 国产精品一二三视频| 亚洲欧美日韩精品| 免费91麻豆精品国产自产在线观看| 亚洲a一级视频| 亚洲欧美一区二区三区四区| 国产精品久久久久久久一区探花| 国产精品久久久久久五月尺| 色播久久人人爽人人爽人人片视av| 亚洲美女免费精品视频在线观看| 日韩一区二区在线视频| 日韩一区二区三区国产| 欧美制服第一页| 亚洲精品720p| 亚洲精品日韩欧美| 欧美日韩亚洲视频| 久久精品电影网| 人人爽久久涩噜噜噜网站| 欧美国产中文字幕| 欧美激情精品久久久久| 亚洲一区亚洲二区亚洲三区| 精品在线欧美视频| 亚洲国产精品高清久久久| 成人情趣片在线观看免费| 久久九九有精品国产23| 中文字幕欧美日韩精品| 青青久久av北条麻妃黑人| 国产精品福利在线观看| 日韩精品久久久久久福利| 欧美日韩午夜视频在线观看| 中文字幕日韩免费视频| 欧美贵妇videos办公室| 91久久精品国产91性色| 亚洲精品一区中文| 亚洲美女精品成人在线视频| 日本精品久久电影| 国产精品久久77777| 伦理中文字幕亚洲| 亚洲福利在线视频| 国产精品爽爽ⅴa在线观看|