iOS-button響應(yīng)流程

Button響應(yīng)首先從觸摸屏幕開始

在這之前刁赖,需要了解坐標(biāo)轉(zhuǎn)換及原因

程序員的邏輯往往如圖所示

image.png

也就是UI邏輯中,使用的坐標(biāo)點(diǎn)往往是相對(duì)于父布局的长搀,而布局會(huì)嵌套多層

屏幕上的觸點(diǎn)乾闰,判斷落點(diǎn)歸屬于哪個(gè)UI控件的話,就需要讓所有UI控件的坐標(biāo)點(diǎn)轉(zhuǎn)換為相對(duì)于 window的

這樣轉(zhuǎn)換后的坐標(biāo)就變?yōu)?/p>

image.png

直觀是這樣的邏輯盈滴,但真實(shí)的檢測過程實(shí)際是 按照ui嵌套層級(jí)關(guān)系遞歸進(jìn)行的涯肩,也就是從window開始轿钠,一級(jí)一級(jí)子視圖倒序遍歷進(jìn)行

這樣在每遞歸到某一層view時(shí),就需要對(duì)此view子視圖進(jìn)行檢測病苗,這個(gè)時(shí)候就需要把當(dāng)前view上的觸點(diǎn)坐標(biāo)轉(zhuǎn)換為 子視圖view上的坐標(biāo)

image.png

說白了疗垛,在檢測階段,每次遞歸檢測時(shí)硫朦,轉(zhuǎn)換坐標(biāo) 就是遍歷子view時(shí)贷腕,point從相對(duì)于當(dāng)前view 改變?yōu)?相對(duì)于 子view,也就是改變了參考基點(diǎn)

簡單梳理流程

image.png
  • 觸摸屏幕
  • IOKit.framework捕捉咬展,封裝IOHIDEvent對(duì)象
  • 通過IPC(進(jìn)程間通信)轉(zhuǎn)發(fā)給SpringBoard進(jìn)程
  • 通過IPC將事件轉(zhuǎn)發(fā)給當(dāng)前活躍的進(jìn)程 AppDelegate
  • app主線程runloop通過port signal(來自于SpringBoard進(jìn)程)檢測到source1, 線程由休眠狀態(tài)被激活,runloop繼續(xù)輪詢
  • runloop檢測到source0(InputSource), 封裝UIEvent泽裳,加入到 當(dāng)前application的event隊(duì)列
  • 事件出隊(duì)列, sendEvent發(fā)送給window
  • window 開始查詢響應(yīng)者
  • rootViewController-view 按照子view 倒序遞歸查詢
    • pointInside 判斷觸點(diǎn)是否落在當(dāng)前view 的bounds內(nèi)
    • hitTest, 如果觸點(diǎn)落在當(dāng)前view的bounds內(nèi), 轉(zhuǎn)換觸點(diǎn)坐標(biāo)為相對(duì)于屏幕的坐標(biāo)點(diǎn),遞歸倒序遍歷子view hitTest檢測
    • 之所以當(dāng)前view子view數(shù)組遍歷采用倒序破婆,最后的view為嵌套層的最上層涮总,效率高
    • 檢測可能出現(xiàn)3種結(jié)果
      • 目標(biāo)響應(yīng)者 ui交互是禁止的 并且不是完全透明 不是隱藏的,結(jié)果就是沒有響應(yīng)者了(nil)
      • view的某個(gè)子視圖 為目標(biāo)響應(yīng)者
      • 當(dāng)前view為 目標(biāo)響應(yīng)者
  • window sendTouchesForEvent 發(fā)送給以上查詢到的響應(yīng)者, 如果響應(yīng)者nil祷舀,就沒有后續(xù)處理了
  • touchBegan/touchMoved/touchEnded/touchCancelled 捕獲處理
  • 回調(diào)響應(yīng)者預(yù)先設(shè)置的 handleCallback瀑梗,也就是 selector, 并傳遞響應(yīng)者自身作為 參數(shù)
    • 根據(jù)touch 幾種邏輯判斷,選擇合適的callback
    • 比如按下按鈕 背景顏色變化
    • 離開按鈕 顏色恢復(fù)等等 各種touch的事件解釋類型, 不同類型執(zhí)行對(duì)應(yīng)不同的callback
  • 如果響應(yīng)者未處理 touch裳扯, 就會(huì)沿著響應(yīng)查找鏈條反向傳遞給父視圖, 直到 application, 也就是如果目標(biāo)響應(yīng)者未響應(yīng)抛丽,會(huì)沿著傳遞鏈條回溯回到 application, application默認(rèn)不做處理
  • 處理結(jié)束,app的runloop進(jìn)入休眠饰豺,等待下次喚醒

apple-touch封裝

touchBegan/touchMoved/touchEnded/touchCancelled 是底層的方式

apple提供了高級(jí)封裝 UIGestureRecognizerUIControl

UIGestureRecognizer 包含8種手勢

  • UITapGestureRecognizer 輕點(diǎn)
  • UIPinchGestureRecognizer 捏和
  • UIRotationGestureRecognizer 旋轉(zhuǎn)
  • UISwipeGestureRecognizer 滑動(dòng)
  • UIPanGestureRecognizer 拖拽
  • UIScreenEdgePanGestureRecognizer 屏幕邊緣拖拽
  • UILongPressGestureRecognizer 長按
  • UIHoverGestureRecognizer 懸停(macOS & iPadOS)

window sendTouchesForEvent 后續(xù)流程修正

上面的流程是基于底層方式描述亿鲜,針對(duì)于apple封裝的 UIGestureRecognizer,做出調(diào)整

window 查詢到具體的 響應(yīng)者之后

  • window sendTouchesForEvent 發(fā)送給以上查詢到的響應(yīng)者; 同時(shí)也會(huì)發(fā)送給 響應(yīng)者視圖綁定的 gestureRecognizers
  • 響應(yīng)者視圖 某個(gè) gestureRecognizer 識(shí)別匹配成功冤吨,就會(huì)回調(diào)響應(yīng)者 touchCancelled方法狡门,響應(yīng)者不再接收 touch事件
  • 由于 手勢互斥,其他的 gestureRecoginzer 也會(huì)回調(diào) touchCancelled方法锅很,且不再接收 touch事件
  • 識(shí)別成功的gesture 設(shè)置的target - action 執(zhí)行
  • 否則其馏,繼續(xù) touchBegan/touchMoved/touchEnded 及后續(xù)處理
  • 處理結(jié)束,app的runloop進(jìn)入休眠爆安,等待下次喚醒

還有一些額外設(shè)定, 比如:

  • 識(shí)別成功之后叛复,是否取消其他響應(yīng) cancelsTouchesInView [true or false]
  • delaysTouchesBegan 是否在手勢識(shí)別失敗之后,才將touchBegin事件傳遞給 響應(yīng)者
  • delaysTouchesEnded 是否在手勢識(shí)別失敗之后扔仓,才將touchEnded事件傳遞給 響應(yīng)者

流程進(jìn)一步細(xì)化

UIControl 是UIView子類

保持前面修正的流程

  • 如果響應(yīng)者 是 UIButton褐奥、UISwitchUISlider 這些系統(tǒng)控件翘簇,也就是 UIControl系統(tǒng)子類, target - action執(zhí)行, 響應(yīng)者不再接收 touchBegan等事件
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末撬码,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子版保,更是在濱河造成了極大的恐慌呜笑,老刑警劉巖夫否,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異叫胁,居然都是意外死亡凰慈,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門驼鹅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來微谓,“玉大人,你說我怎么就攤上這事输钩〔蛐停” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵买乃,是天一觀的道長姻氨。 經(jīng)常有香客問我,道長为牍,這世上最難降的妖魔是什么哼绑? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任岩馍,我火速辦了婚禮碉咆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蛀恩。我一直安慰自己疫铜,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布双谆。 她就那樣靜靜地躺著壳咕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪顽馋。 梳的紋絲不亂的頭發(fā)上谓厘,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音寸谜,去河邊找鬼竟稳。 笑死,一個(gè)胖子當(dāng)著我的面吹牛熊痴,可吹牛的內(nèi)容都是我干的他爸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼果善,長吁一口氣:“原來是場噩夢啊……” “哼诊笤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起巾陕,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤讨跟,失蹤者是張志新(化名)和其女友劉穎纪他,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體许赃,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡止喷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了混聊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片弹谁。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖句喜,靈堂內(nèi)的尸體忽然破棺而出预愤,到底是詐尸還是另有隱情,我是刑警寧澤咳胃,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布植康,位于F島的核電站,受9級(jí)特大地震影響展懈,放射性物質(zhì)發(fā)生泄漏销睁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一存崖、第九天 我趴在偏房一處隱蔽的房頂上張望冻记。 院中可真熱鬧,春花似錦来惧、人聲如沸冗栗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽隅居。三九已至,卻和暖如春葛虐,著一層夾襖步出監(jiān)牢的瞬間胎源,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國打工屿脐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涕蚤,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓摄悯,卻偏偏與公主長得像赞季,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子奢驯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

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

  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時(shí)...
    歐辰_OSR閱讀 29,371評(píng)論 8 265
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,096評(píng)論 1 32
  • iOS的應(yīng)用中申钩,用戶與App進(jìn)行交互,會(huì)產(chǎn)生很多事件瘪阁,這些事件是如何產(chǎn)生撒遣,響應(yīng)的鏈條又是怎樣傳遞的呢邮偎,下面將會(huì)一一...
    limeng99閱讀 607評(píng)論 1 1
  • 按照時(shí)間順序,事件的生命周期是這樣的: 事件的產(chǎn)生和傳遞(事件如何從父控件傳遞到子控件并尋找到最合適的view义黎、尋...
    kadis閱讀 785評(píng)論 0 2
  • 假如我們點(diǎn)擊了手機(jī)屏幕??廉涕,那么當(dāng)前頁面的app需要識(shí)別出點(diǎn)擊的是哪一個(gè)控件泻云,并且對(duì)事件的響應(yīng)進(jìn)行處理。而iOS系統(tǒng)...
    Fat_Blog閱讀 3,746評(píng)論 2 11