iOS事件

概述

iOS中事件有觸摸事件睁冬、加速計事件召锈、遠程控制事件,下面以觸摸事件為例研究下iOS事件相關(guān)的內(nèi)容


iOS事件分類

UIResponsder

iOS中繼承了UIResponsder的對象才能夠響應(yīng)事件,如UIViewController描函、UIView今膊、UIApplication些阅。
UIResponsder能夠響應(yīng)事件的原因是:提供了幾個方法來處理事件

//觸摸事件
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;//手指觸摸事件開始時調(diào)用該方法
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;//手指在屏幕上移動時調(diào)用該方法
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

//加速計事件
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event;
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event;
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event;

//遠程控制事件
- (void)remoteControlReceivedWithEvent:(UIEvent *)event;

備注:

  1. 當多個手指同時觸摸屏幕時,只會調(diào)用一次touchesBegan:withEvent:方法斑唬,touches中包含多個UITouch對象市埋,分別對應(yīng)著觸摸屏幕的手指
  2. 如果是UIViewController的事件昌跌,在UIViewController中重寫上面用到的方法即可件炉;如果是UIView的事件,需要在子類中重寫上面用到的方法

實例:觸摸屏幕篡撵,移動屏幕上的某個UIButton

UIView的子類中重寫touchesMoved: withEvent:方法

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self];//當前點的位置
    CGPoint previousPoint = [touch previousLocationInView:self];//上一個點的位置
    CGFloat xPoint = point.x - previousPoint.x;
    CGFloat yPoint = point.y - previousPoint.y;
    NSLog(@"point:%@;previousPoint:%@;xPoint:%f;yPoint:%f",NSStringFromCGPoint(point), NSStringFromCGPoint(previousPoint), xPoint, yPoint);
    CGPoint centerPoint = self.btn.center;
    centerPoint = CGPointMake(centerPoint.x + xPoint, centerPoint.y + yPoint);
    self.btn.center = centerPoint;
}

iOS 事件處理過程

iOS事件分為事件傳遞褐着、事件響應(yīng)兩個過程坷澡。

事件的產(chǎn)生

發(fā)生觸摸事件后,系統(tǒng)會將事件加入到由UIApplication管理的隊列(先進先出FIFO)献起,然后將隊列最前面的事件分發(fā)下去:UIApplication->keyWindow->視圖層次結(jié)構(gòu)洋访,找到合適的視圖控件后,就會調(diào)用對應(yīng)控件的事件方法(touchesBegan: withEvent:等)來處理對應(yīng)的事件谴餐。

事件的傳遞

觸摸事件的傳遞是從父控件傳遞到子控件

  • 尋找響應(yīng)事件的控件步驟
    1. 首先判斷keyWindow是否能響應(yīng)事件
    2. 觸摸點是否在自己身上
    3. 從后往前遍歷子控件姻政,重復(fù)前面的兩個步驟(首先查找數(shù)組中最后一個元素)
    4. 如果沒有符合條件的子控件,那就認為自己可以處理
  • UIView不能響應(yīng)事件的三種情況
  1. 不允許交互userInteractionEnabled = NO
  2. 隱藏的控件不能接收事件
  3. 透明度:如果設(shè)置一個控件的透明度<0.01岂嗓,會直接影響子控件的透明度汁展。

事件傳遞實例

注意:如果父控件不能接收觸摸事件,那么子控件就不可能接收到觸摸事件

事件傳遞實例

查找符合條件的控件原理

主要是通過以下兩個控件實現(xiàn)查找

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;//返回nil厌殉,表明當前view以及子view沒有能夠響應(yīng)事件的;如果不為nil食绿,則表明當前view中有能響應(yīng)事件的
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;//返回YES,表明觸摸點在當前view中

通過調(diào)用hitTest:withEvent:可以判斷是否有能夠響應(yīng)事件的控件公罕,具體步驟為:
產(chǎn)生觸摸事件->UIApplication事件隊列->[UIWindow hitTest:withEvent:]->返回合適的view->[子控件 hitTest:withEvent:]->返回合適的view
不過子控件是否能夠響應(yīng)事件器紧,父控件都會把事件傳遞給子控件,如果子控件不能響應(yīng)事件楼眷,則父控件響應(yīng)事件

實例:view中的button響應(yīng)事件

參考iOS超出父視圖后點擊事件不響應(yīng)铲汪,文中想要view中的button響應(yīng)點擊事件,因此重寫了hitTest:withEvent:方法

響應(yīng)者鏈

在iOS程序中無論是最后面的UIWindow還是最前面的某個按鈕罐柳,它們的擺放是有前后關(guān)系的掌腰,一個控件可以放到另一個控件上面或下面,那么用戶點擊某個控件時是觸發(fā)上面的控件還是下面的控件呢张吉,這種先后關(guān)系構(gòu)成一個鏈條就叫“響應(yīng)者鏈”齿梁。

事件響應(yīng)過程
  • 如果當前控件無法響應(yīng)事件,就將事件按照視圖層級結(jié)構(gòu)(最上層是根視圖)向上傳遞。如果當前view是控制器的view勺择,那么控制器就是上一個響應(yīng)者创南,事件就傳遞給控制器;如果當前view不是控制器的view酵幕,那么父視圖就是當前view的上一個響應(yīng)者扰藕,事件就傳遞給它的父視圖
  • 在視圖層次結(jié)構(gòu)的最頂級視圖,如果也不能處理收到的事件或消息芳撒,則其將事件或消息傳遞給window對象進行處理
  • 如果window對象也不處理邓深,則其將事件或消息傳遞給UIApplication對象
  • 如果UIApplication也不能處理該事件或消息,則將其丟棄

總結(jié)

  1. 觸摸屏幕產(chǎn)生觸摸事件后笔刹,觸摸事件會被添加到由UIApplication管理的事件隊列中
  2. UIApplication會從事件隊列中取出最前面的事件芥备,把事件傳遞給keyWindow
  3. keyWindow會在視圖層次結(jié)構(gòu)中找到一個最合適的視圖來處理觸摸事件
  4. 最合適的view會調(diào)用自己的touches方法處理事件,如果不能處理事件舌菜,就將事件沿著響應(yīng)者鏈向上拋

問題與解決方案

  1. 向 WKWebView 添加 UITapGestureRecognizer 點擊識別萌壳,會發(fā)現(xiàn)不起作用,怎樣解決日月?
    解決:實現(xiàn) gesture 的 delegate袱瓮,允許兩個 gesture 同時識別
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }

附圖

UIResponder

UIKit 結(jié)構(gòu)圖

參考

  1. iOS事件傳遞->處理->響應(yīng)
  2. iOS超出父視圖后點擊事件不響應(yīng)
  3. iOS觸摸事件全家桶
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市爱咬,隨后出現(xiàn)的幾起案子尺借,更是在濱河造成了極大的恐慌,老刑警劉巖精拟,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件燎斩,死亡現(xiàn)場離奇詭異,居然都是意外死亡蜂绎,警方通過查閱死者的電腦和手機栅表,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來师枣,“玉大人怪瓶,你說我怎么就攤上這事〖溃” “怎么了劳殖?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長拨脉。 經(jīng)常有香客問我,道長宣增,這世上最難降的妖魔是什么玫膀? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮爹脾,結(jié)果婚禮上帖旨,老公的妹妹穿的比我還像新娘箕昭。我一直安慰自己,他們只是感情好解阅,可當我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布落竹。 她就那樣靜靜地躺著,像睡著了一般货抄。 火紅的嫁衣襯著肌膚如雪述召。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天蟹地,我揣著相機與錄音积暖,去河邊找鬼。 笑死怪与,一個胖子當著我的面吹牛夺刑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播分别,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼遍愿,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了耘斩?” 一聲冷哼從身側(cè)響起沼填,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎煌往,沒想到半個月后倾哺,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡刽脖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年羞海,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片曲管。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡却邓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出院水,到底是詐尸還是另有隱情腊徙,我是刑警寧澤,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布檬某,位于F島的核電站撬腾,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏恢恼。R本人自食惡果不足惜民傻,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧漓踢,春花似錦牵署、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至挺据,卻和暖如春取具,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背吴菠。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工者填, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人做葵。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓占哟,卻偏偏與公主長得像,于是被迫代替她去往敵國和親酿矢。 傳聞我的和親對象是個殘疾皇子榨乎,可洞房花燭夜當晚...
    茶點故事閱讀 44,974評論 2 355

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

  • 用戶以多種方式操縱他們的iOS設(shè)備,例如觸摸屏幕或搖動設(shè)備瘫筐。 iOS會解釋用戶何時以及如何操作硬件并將此信息傳遞到...
    坤坤同學(xué)閱讀 3,997評論 7 19
  • 本次筆記主要是整理一下關(guān)于 iOS 中關(guān)于事件傳遞和響應(yīng)機制蜜暑,參考了一些其他資料加上自己的理解。 事件 Event...
    varlarzh閱讀 329評論 0 2
  • 事件傳遞:響應(yīng)者鏈 當你設(shè)計一個app的時候策肝,你很可能需要你的app能夠動態(tài)響應(yīng)某些事件肛捍。比如,觸摸可以發(fā)生在屏幕...
    hjfrun閱讀 1,033評論 1 5
  • 本篇主要講解iOS事件傳遞的整個過程之众,大部分內(nèi)容翻譯自Apple Developer Guide拙毫,原文鏈接 當一個...
    Little_Mango閱讀 1,275評論 4 10
  • 本文主要參考了 VV木公子(簡書作者)的 史上最詳細的iOS之事件的傳遞和響應(yīng)機制我按照自己的理解做了排版和一些表...
    hi_xgb閱讀 2,617評論 4 28